Merge branch 'new-member-page' into 'master'
Improve group and project members pages * Improve UI for group members page * Improve UI for project members page For internal issue https://dev.gitlab.org/gitlab/gitlabhq/issues/2057 This MR should solve usability problem with adding new member to group/project See merge request !1886
This commit is contained in:
commit
dee28c50a9
19 changed files with 457 additions and 489 deletions
|
@ -127,3 +127,8 @@ ul.content-list {
|
|||
}
|
||||
}
|
||||
|
||||
.panel > .content-list {
|
||||
li {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,3 +32,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel > .gl-pagination {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
.new-group-member-holder {
|
||||
margin-top: 50px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.member-search-form {
|
||||
float: left;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
%li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)}
|
||||
%span{class: ("list-item-name" if show_controls)}
|
||||
- if member.user
|
||||
= image_tag avatar_icon(user, 16), class: "avatar s16", alt: ''
|
||||
= image_tag avatar_icon(user, 24), class: "avatar s24", alt: ''
|
||||
%strong
|
||||
= link_to user.name, user_path(user)
|
||||
%span.cgray= user.username
|
||||
|
@ -14,7 +14,7 @@
|
|||
%label.label.label-danger
|
||||
%strong Blocked
|
||||
- else
|
||||
= image_tag avatar_icon(member.invite_email, 16), class: "avatar s16", alt: ''
|
||||
= image_tag avatar_icon(member.invite_email, 24), class: "avatar s24", alt: ''
|
||||
%strong
|
||||
= member.invite_email
|
||||
%span.cgray
|
||||
|
|
|
@ -1,38 +1,35 @@
|
|||
- page_title "Members"
|
||||
- header_title group_title(@group, "Members", group_group_members_path(@group))
|
||||
- if should_user_see_group_roles?(current_user, @group)
|
||||
- @blank_container = true
|
||||
|
||||
.group-members-page
|
||||
- if current_user && current_user.can?(:admin_group_member, @group)
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
Add new user to group
|
||||
.panel-body
|
||||
- if should_user_see_group_roles?(current_user, @group)
|
||||
%p.light
|
||||
Members of group have access to all group projects.
|
||||
Read more about permissions
|
||||
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
|
||||
|
||||
|
||||
.clearfix.js-toggle-container
|
||||
= form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input', spellcheck: false }
|
||||
= button_tag 'Search', class: 'btn'
|
||||
|
||||
- if current_user && current_user.can?(:admin_group_member, @group)
|
||||
.pull-right
|
||||
= button_tag class: 'btn btn-new js-toggle-button', type: 'button' do
|
||||
Add members
|
||||
%i.fa.fa-chevron-down
|
||||
|
||||
.js-toggle-content.hide.new-group-member-holder
|
||||
.new-group-member-holder
|
||||
= render "new_group_member"
|
||||
|
||||
.panel.panel-default.prepend-top-20
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%strong #{@group.name}
|
||||
group members
|
||||
%small
|
||||
(#{@members.total_count})
|
||||
%ul.well-list
|
||||
.pull-right
|
||||
= form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control', spellcheck: false }
|
||||
= button_tag class: 'btn', title: 'Search' do
|
||||
= icon("search")
|
||||
%ul.content-list
|
||||
- @members.each do |member|
|
||||
= render 'groups/group_members/group_member', member: member, show_controls: true
|
||||
|
||||
= paginate @members, theme: 'gitlab'
|
||||
= paginate @members, theme: 'gitlab'
|
||||
|
||||
:javascript
|
||||
$('form.member-search-form').on('submit', function(event) {
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
group members
|
||||
%small
|
||||
(#{members.count})
|
||||
.panel-head-actions
|
||||
= link_to group_group_members_path(@group), class: 'btn btn-sm' do
|
||||
%i.fa.fa-pencil-square-o
|
||||
.pull-right
|
||||
= link_to group_group_members_path(@group), class: 'btn' do
|
||||
= icon('pencil-square-o')
|
||||
Edit group members
|
||||
%ul.well-list
|
||||
%ul.content-list
|
||||
- members.each do |member|
|
||||
= render 'groups/group_members/group_member', member: member, show_controls: false
|
||||
- if members.count > 20
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
%li{class: "#{dom_class(member)} js-toggle-container project_member_row access-#{member.human_access.downcase}", id: dom_id(member)}
|
||||
%span.list-item-name
|
||||
- if member.user
|
||||
= image_tag avatar_icon(user, 16), class: "avatar s16", alt: ''
|
||||
= image_tag avatar_icon(user, 24), class: "avatar s24", alt: ''
|
||||
%strong
|
||||
= link_to user.name, user_path(user)
|
||||
%span.cgray= user.username
|
||||
|
@ -14,7 +14,7 @@
|
|||
%label.label.label-danger
|
||||
%strong Blocked
|
||||
- else
|
||||
= image_tag avatar_icon(member.invite_email, 16), class: "avatar s16", alt: ''
|
||||
= image_tag avatar_icon(member.invite_email, 24), class: "avatar s24", alt: ''
|
||||
%strong
|
||||
= member.invite_email
|
||||
%span.cgray
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
.panel.panel-default.prepend-top-20
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%strong #{@project.name}
|
||||
project members
|
||||
%small
|
||||
(#{members.count})
|
||||
%ul.well-list
|
||||
.pull-right
|
||||
= form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control', spellcheck: false }
|
||||
= button_tag class: 'btn', title: 'Search' do
|
||||
= icon("search")
|
||||
%ul.content-list
|
||||
- members.each do |project_member|
|
||||
= render 'project_member', member: project_member
|
||||
|
||||
:javascript
|
||||
$('form.member-search-form').on('submit', function (event) {
|
||||
event.preventDefault();
|
||||
Turbolinks.visit(this.action + '?' + $(this).serialize());
|
||||
});
|
||||
|
|
|
@ -1,36 +1,21 @@
|
|||
- page_title "Members"
|
||||
= render "header_title"
|
||||
- @blank_container = true
|
||||
|
||||
.gray-content-block.top-block
|
||||
.clearfix.js-toggle-container
|
||||
= form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do
|
||||
.form-group
|
||||
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input', spellcheck: false }
|
||||
= button_tag 'Search', class: 'btn'
|
||||
|
||||
.project-members-page
|
||||
- if can?(current_user, :admin_project_member, @project)
|
||||
%span.pull-right
|
||||
= button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do
|
||||
Add members
|
||||
%i.fa.fa-chevron-down
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
Add new user to project
|
||||
.pull-right
|
||||
= link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do
|
||||
Import members
|
||||
|
||||
.js-toggle-content.hide.new-group-member-holder
|
||||
.panel-body
|
||||
%p.light
|
||||
Users with access to this project are listed below.
|
||||
= render "new_project_member"
|
||||
|
||||
%p.prepend-top-default.light
|
||||
Users with access to this project are listed below.
|
||||
Read more about project permissions
|
||||
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
|
||||
= render "team", members: @project_members
|
||||
|
||||
= render "team", members: @project_members
|
||||
|
||||
- if @group
|
||||
- if @group
|
||||
= render "group_members", members: @group_members
|
||||
|
||||
:javascript
|
||||
$('form.member-search-form').on('submit', function (event) {
|
||||
event.preventDefault();
|
||||
Turbolinks.visit(this.action + '?' + $(this).serialize());
|
||||
});
|
||||
|
|
105
features/group/members.feature
Normal file
105
features/group/members.feature
Normal file
|
@ -0,0 +1,105 @@
|
|||
Feature: Group Members
|
||||
Background:
|
||||
Given I sign in as "John Doe"
|
||||
And "John Doe" is owner of group "Owned"
|
||||
And "John Doe" is guest of group "Guest"
|
||||
|
||||
@javascript
|
||||
Scenario: I should add user to group "Owned"
|
||||
Given User "Mary Jane" exists
|
||||
When I visit group "Owned" members page
|
||||
And I select user "Mary Jane" from list with role "Reporter"
|
||||
Then I should see user "Mary Jane" in team list
|
||||
|
||||
@javascript
|
||||
Scenario: Add user to group
|
||||
Given gitlab user "Mike"
|
||||
When I visit group "Owned" members page
|
||||
When I select "Mike" as "Reporter"
|
||||
Then I should see "Mike" in team list as "Reporter"
|
||||
|
||||
@javascript
|
||||
Scenario: Ignore add user to group when is already Owner
|
||||
Given gitlab user "Mike"
|
||||
When I visit group "Owned" members page
|
||||
When I select "Mike" as "Reporter"
|
||||
Then I should see "Mike" in team list as "Owner"
|
||||
|
||||
@javascript
|
||||
Scenario: Invite user to group
|
||||
When I visit group "Owned" members page
|
||||
When I select "sjobs@apple.com" as "Reporter"
|
||||
Then I should see "sjobs@apple.com" in team list as invited "Reporter"
|
||||
|
||||
@javascript
|
||||
Scenario: Edit group member permissions
|
||||
Given "Mary Jane" is guest of group "Owned"
|
||||
And I visit group "Owned" members page
|
||||
When I change the "Mary Jane" role to "Developer"
|
||||
Then I should see "Mary Jane" as "Developer"
|
||||
|
||||
# Leave
|
||||
|
||||
@javascript
|
||||
Scenario: Owner should be able to remove himself from group if he is not the last owner
|
||||
Given "Mary Jane" is owner of group "Owned"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
When I click on the "Remove User From Group" button for "John Doe"
|
||||
And I visit group "Owned" members page
|
||||
Then I should not see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
|
||||
@javascript
|
||||
Scenario: Owner should not be able to remove himself from group if he is the last owner
|
||||
Given "Mary Jane" is guest of group "Owned"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
Then I should not see the "Remove User From Group" button for "John Doe"
|
||||
|
||||
@javascript
|
||||
Scenario: Guest should be able to remove himself from group
|
||||
Given "Mary Jane" is guest of group "Guest"
|
||||
When I visit group "Guest" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
When I click on the "Remove User From Group" button for "John Doe"
|
||||
When I visit group "Guest" members page
|
||||
Then I should not see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
|
||||
@javascript
|
||||
Scenario: Guest should be able to remove himself from group even if he is the only user in the group
|
||||
When I visit group "Guest" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
When I click on the "Remove User From Group" button for "John Doe"
|
||||
When I visit group "Guest" members page
|
||||
Then I should not see user "John Doe" in team list
|
||||
|
||||
# Remove others
|
||||
|
||||
Scenario: Owner should be able to remove other users from group
|
||||
Given "Mary Jane" is owner of group "Owned"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
When I click on the "Remove User From Group" button for "Mary Jane"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should not see user "Mary Jane" in team list
|
||||
|
||||
Scenario: Guest should not be able to remove other users from group
|
||||
Given "Mary Jane" is guest of group "Guest"
|
||||
When I visit group "Guest" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
Then I should not see the "Remove User From Group" button for "Mary Jane"
|
||||
|
||||
Scenario: Search member by name
|
||||
Given "Mary Jane" is guest of group "Guest"
|
||||
And I visit group "Guest" members page
|
||||
When I search for 'Mary' member
|
||||
Then I should see user "Mary Jane" in team list
|
||||
Then I should not see user "John Doe" in team list
|
30
features/group/milestones.feature
Normal file
30
features/group/milestones.feature
Normal file
|
@ -0,0 +1,30 @@
|
|||
Feature: Group Milestones
|
||||
Background:
|
||||
Given I sign in as "John Doe"
|
||||
And "John Doe" is owner of group "Owned"
|
||||
|
||||
Scenario: I should see group "Owned" milestone index page with no milestones
|
||||
When I visit group "Owned" page
|
||||
And I click on group milestones
|
||||
Then I should see group milestones index page has no milestones
|
||||
|
||||
Scenario: I should see group "Owned" milestone index page with milestones
|
||||
Given Group has projects with milestones
|
||||
When I visit group "Owned" page
|
||||
And I click on group milestones
|
||||
Then I should see group milestones index page with milestones
|
||||
|
||||
Scenario: I should see group "Owned" milestone show page
|
||||
Given Group has projects with milestones
|
||||
When I visit group "Owned" page
|
||||
And I click on group milestones
|
||||
And I click on one group milestone
|
||||
Then I should see group milestone with descriptions and expiry date
|
||||
And I should see group milestone with all issues and MRs assigned to that milestone
|
||||
|
||||
Scenario: Create multiple milestones with one form
|
||||
Given I visit group "Owned" milestones page
|
||||
And I click new milestone button
|
||||
And I fill milestone name
|
||||
When I press create mileston button
|
||||
Then milestone in each project should be created
|
|
@ -2,7 +2,6 @@ Feature: Groups
|
|||
Background:
|
||||
Given I sign in as "John Doe"
|
||||
And "John Doe" is owner of group "Owned"
|
||||
And "John Doe" is guest of group "Guest"
|
||||
|
||||
Scenario: I should have back to group button
|
||||
When I visit group "Owned" page
|
||||
|
@ -24,13 +23,6 @@ Feature: Groups
|
|||
When I visit group "Owned" merge requests page
|
||||
Then I should see merge requests from group "Owned" assigned to me
|
||||
|
||||
@javascript
|
||||
Scenario: I should add user to projects in group "Owned"
|
||||
Given User "Mary Jane" exists
|
||||
When I visit group "Owned" members page
|
||||
And I select user "Mary Jane" from list with role "Reporter"
|
||||
Then I should see user "Mary Jane" in team list
|
||||
|
||||
Scenario: I should see edit group "Owned" page
|
||||
When I visit group "Owned" settings page
|
||||
And I change group "Owned" name to "new-name"
|
||||
|
@ -51,130 +43,6 @@ Feature: Groups
|
|||
Then I should not see group "Owned" avatar
|
||||
And I should not see the "Remove avatar" button
|
||||
|
||||
@javascript
|
||||
Scenario: Add user to group
|
||||
Given gitlab user "Mike"
|
||||
When I visit group "Owned" members page
|
||||
And I click link "Add members"
|
||||
When I select "Mike" as "Reporter"
|
||||
Then I should see "Mike" in team list as "Reporter"
|
||||
|
||||
@javascript
|
||||
Scenario: Ignore add user to group when is already Owner
|
||||
Given gitlab user "Mike"
|
||||
When I visit group "Owned" members page
|
||||
And I click link "Add members"
|
||||
When I select "Mike" as "Reporter"
|
||||
Then I should see "Mike" in team list as "Owner"
|
||||
|
||||
@javascript
|
||||
Scenario: Invite user to group
|
||||
When I visit group "Owned" members page
|
||||
And I click link "Add members"
|
||||
When I select "sjobs@apple.com" as "Reporter"
|
||||
Then I should see "sjobs@apple.com" in team list as invited "Reporter"
|
||||
|
||||
@javascript
|
||||
Scenario: Edit group member permissions
|
||||
Given "Mary Jane" is guest of group "Owned"
|
||||
And I visit group "Owned" members page
|
||||
When I change the "Mary Jane" role to "Developer"
|
||||
Then I should see "Mary Jane" as "Developer"
|
||||
|
||||
# Leave
|
||||
|
||||
@javascript
|
||||
Scenario: Owner should be able to remove himself from group if he is not the last owner
|
||||
Given "Mary Jane" is owner of group "Owned"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
When I click on the "Remove User From Group" button for "John Doe"
|
||||
And I visit group "Owned" members page
|
||||
Then I should not see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
|
||||
@javascript
|
||||
Scenario: Owner should not be able to remove himself from group if he is the last owner
|
||||
Given "Mary Jane" is guest of group "Owned"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
Then I should not see the "Remove User From Group" button for "John Doe"
|
||||
|
||||
@javascript
|
||||
Scenario: Guest should be able to remove himself from group
|
||||
Given "Mary Jane" is guest of group "Guest"
|
||||
When I visit group "Guest" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
When I click on the "Remove User From Group" button for "John Doe"
|
||||
When I visit group "Guest" members page
|
||||
Then I should not see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
|
||||
@javascript
|
||||
Scenario: Guest should be able to remove himself from group even if he is the only user in the group
|
||||
When I visit group "Guest" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
When I click on the "Remove User From Group" button for "John Doe"
|
||||
When I visit group "Guest" members page
|
||||
Then I should not see user "John Doe" in team list
|
||||
|
||||
# Remove others
|
||||
|
||||
Scenario: Owner should be able to remove other users from group
|
||||
Given "Mary Jane" is owner of group "Owned"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
When I click on the "Remove User From Group" button for "Mary Jane"
|
||||
When I visit group "Owned" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should not see user "Mary Jane" in team list
|
||||
|
||||
Scenario: Guest should not be able to remove other users from group
|
||||
Given "Mary Jane" is guest of group "Guest"
|
||||
When I visit group "Guest" members page
|
||||
Then I should see user "John Doe" in team list
|
||||
Then I should see user "Mary Jane" in team list
|
||||
Then I should not see the "Remove User From Group" button for "Mary Jane"
|
||||
|
||||
Scenario: Search member by name
|
||||
Given "Mary Jane" is guest of group "Guest"
|
||||
And I visit group "Guest" members page
|
||||
When I search for 'Mary' member
|
||||
Then I should see user "Mary Jane" in team list
|
||||
Then I should not see user "John Doe" in team list
|
||||
|
||||
# Group milestones
|
||||
|
||||
Scenario: I should see group "Owned" milestone index page with no milestones
|
||||
When I visit group "Owned" page
|
||||
And I click on group milestones
|
||||
Then I should see group milestones index page has no milestones
|
||||
|
||||
Scenario: I should see group "Owned" milestone index page with milestones
|
||||
Given Group has projects with milestones
|
||||
When I visit group "Owned" page
|
||||
And I click on group milestones
|
||||
Then I should see group milestones index page with milestones
|
||||
|
||||
Scenario: I should see group "Owned" milestone show page
|
||||
Given Group has projects with milestones
|
||||
When I visit group "Owned" page
|
||||
And I click on group milestones
|
||||
And I click on one group milestone
|
||||
Then I should see group milestone with descriptions and expiry date
|
||||
And I should see group milestone with all issues and MRs assigned to that milestone
|
||||
|
||||
Scenario: Create multiple milestones with one form
|
||||
Given I visit group "Owned" milestones page
|
||||
And I click new milestone button
|
||||
And I fill milestone name
|
||||
When I press create mileston button
|
||||
Then milestone in each project should be created
|
||||
|
||||
# Group projects in settings
|
||||
Scenario: I should see all projects in the project list in settings
|
||||
Given Group "Owned" has archived project
|
||||
|
|
|
@ -13,14 +13,12 @@ Feature: Project Team Management
|
|||
|
||||
@javascript
|
||||
Scenario: Add user to project
|
||||
Given I click link "Add members"
|
||||
And I select "Mike" as "Reporter"
|
||||
When I select "Mike" as "Reporter"
|
||||
Then I should see "Mike" in team list as "Reporter"
|
||||
|
||||
@javascript
|
||||
Scenario: Invite user to project
|
||||
Given I click link "Add members"
|
||||
And I select "sjobs@apple.com" as "Reporter"
|
||||
When I select "sjobs@apple.com" as "Reporter"
|
||||
Then I should see "sjobs@apple.com" in team list as invited "Reporter"
|
||||
|
||||
@javascript
|
||||
|
|
147
features/steps/group/members.rb
Normal file
147
features/steps/group/members.rb
Normal file
|
@ -0,0 +1,147 @@
|
|||
class Spinach::Features::GroupMembers < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedGroup
|
||||
include SharedUser
|
||||
include Select2Helper
|
||||
|
||||
step 'I select "Mike" as "Reporter"' do
|
||||
user = User.find_by(name: "Mike")
|
||||
|
||||
page.within ".users-group-form" do
|
||||
select2(user.id, from: "#user_ids", multiple: true)
|
||||
select "Reporter", from: "access_level"
|
||||
end
|
||||
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I select "Mike" as "Master"' do
|
||||
user = User.find_by(name: "Mike")
|
||||
|
||||
page.within ".users-group-form" do
|
||||
select2(user.id, from: "#user_ids", multiple: true)
|
||||
select "Master", from: "access_level"
|
||||
end
|
||||
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I should see "Mike" in team list as "Reporter"' do
|
||||
page.within '.content-list' do
|
||||
expect(page).to have_content('Mike')
|
||||
expect(page).to have_content('Reporter')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see "Mike" in team list as "Owner"' do
|
||||
page.within '.content-list' do
|
||||
expect(page).to have_content('Mike')
|
||||
expect(page).to have_content('Owner')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I select "sjobs@apple.com" as "Reporter"' do
|
||||
page.within ".users-group-form" do
|
||||
select2("sjobs@apple.com", from: "#user_ids", multiple: true)
|
||||
select "Reporter", from: "access_level"
|
||||
end
|
||||
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do
|
||||
page.within '.content-list' do
|
||||
expect(page).to have_content('sjobs@apple.com')
|
||||
expect(page).to have_content('invited')
|
||||
expect(page).to have_content('Reporter')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I select user "Mary Jane" from list with role "Reporter"' do
|
||||
user = User.find_by(name: "Mary Jane") || create(:user, name: "Mary Jane")
|
||||
|
||||
page.within ".users-group-form" do
|
||||
select2(user.id, from: "#user_ids", multiple: true)
|
||||
select "Reporter", from: "access_level"
|
||||
end
|
||||
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I should see user "John Doe" in team list' do
|
||||
expect(group_members_list).to have_content("John Doe")
|
||||
end
|
||||
|
||||
step 'I should not see user "John Doe" in team list' do
|
||||
expect(group_members_list).not_to have_content("John Doe")
|
||||
end
|
||||
|
||||
step 'I should see user "Mary Jane" in team list' do
|
||||
expect(group_members_list).to have_content("Mary Jane")
|
||||
end
|
||||
|
||||
step 'I should not see user "Mary Jane" in team list' do
|
||||
expect(group_members_list).not_to have_content("Mary Jane")
|
||||
end
|
||||
|
||||
step 'I click on the "Remove User From Group" button for "John Doe"' do
|
||||
find(:css, 'li', text: "John Doe").find(:css, 'a.btn-remove').click
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I click on the "Remove User From Group" button for "Mary Jane"' do
|
||||
find(:css, 'li', text: "Mary Jane").find(:css, 'a.btn-remove').click
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I should not see the "Remove User From Group" button for "John Doe"' do
|
||||
expect(find(:css, 'li', text: "John Doe")).not_to have_selector(:css, 'a.btn-remove')
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I should not see the "Remove User From Group" button for "Mary Jane"' do
|
||||
expect(find(:css, 'li', text: "Mary Jane")).not_to have_selector(:css, 'a.btn-remove')
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I search for \'Mary\' member' do
|
||||
page.within '.member-search-form' do
|
||||
fill_in 'search', with: 'Mary'
|
||||
click_button 'Search'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I change the "Mary Jane" role to "Developer"' do
|
||||
member = mary_jane_member
|
||||
|
||||
page.within "#group_member_#{member.id}" do
|
||||
find(".js-toggle-button").click
|
||||
page.within "#edit_group_member_#{member.id}" do
|
||||
select 'Developer', from: 'group_member_access_level'
|
||||
click_on 'Save'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see "Mary Jane" as "Developer"' do
|
||||
member = mary_jane_member
|
||||
|
||||
page.within "#group_member_#{member.id}" do
|
||||
page.within '.member-access-level' do
|
||||
expect(page).to have_content "Developer"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mary_jane_member
|
||||
user = User.find_by(name: "Mary Jane")
|
||||
owned_group.members.find_by(user_id: user.id)
|
||||
end
|
||||
|
||||
def group_members_list
|
||||
find(".panel .content-list")
|
||||
end
|
||||
end
|
90
features/steps/group/milestones.rb
Normal file
90
features/steps/group/milestones.rb
Normal file
|
@ -0,0 +1,90 @@
|
|||
class Spinach::Features::GroupMilestones < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedGroup
|
||||
include SharedUser
|
||||
|
||||
step 'I click on group milestones' do
|
||||
click_link 'Milestones'
|
||||
end
|
||||
|
||||
step 'I should see group milestones index page has no milestones' do
|
||||
expect(page).to have_content('No milestones to show')
|
||||
end
|
||||
|
||||
step 'Group has projects with milestones' do
|
||||
group_milestone
|
||||
end
|
||||
|
||||
step 'I should see group milestones index page with milestones' do
|
||||
expect(page).to have_content('Version 7.2')
|
||||
expect(page).to have_content('GL-113')
|
||||
expect(page).to have_link('3 Issues', href: issues_group_path("owned", milestone_title: "Version 7.2"))
|
||||
expect(page).to have_link('0 Merge Requests', href: merge_requests_group_path("owned", milestone_title: "GL-113"))
|
||||
end
|
||||
|
||||
step 'I click on one group milestone' do
|
||||
click_link 'GL-113'
|
||||
end
|
||||
|
||||
step 'I should see group milestone with descriptions and expiry date' do
|
||||
expect(page).to have_content('expires at Aug 20, 2114')
|
||||
end
|
||||
|
||||
step 'I should see group milestone with all issues and MRs assigned to that milestone' do
|
||||
expect(page).to have_content('Milestone GL-113')
|
||||
expect(page).to have_content('Progress: 0 closed – 3 open')
|
||||
issue = Milestone.find_by(name: 'GL-113').issues.first
|
||||
expect(page).to have_link(issue.title, href: namespace_project_issue_path(issue.project.namespace, issue.project, issue))
|
||||
end
|
||||
|
||||
step 'I fill milestone name' do
|
||||
fill_in 'milestone_title', with: 'v2.9.0'
|
||||
end
|
||||
|
||||
step 'I click new milestone button' do
|
||||
click_link "New Milestone"
|
||||
end
|
||||
|
||||
step 'I press create mileston button' do
|
||||
click_button "Create Milestone"
|
||||
end
|
||||
|
||||
step 'milestone in each project should be created' do
|
||||
group = Group.find_by(name: 'Owned')
|
||||
expect(page).to have_content "Milestone v2.9.0"
|
||||
expect(group.projects).to be_present
|
||||
|
||||
group.projects.each do |project|
|
||||
expect(page).to have_content project.name
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def group_milestone
|
||||
group = owned_group
|
||||
|
||||
%w(gitlabhq gitlab-ci cookbook-gitlab).each do |path|
|
||||
project = create :project, path: path, group: group
|
||||
milestone = create :milestone, title: "Version 7.2", project: project
|
||||
create :issue,
|
||||
project: project,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone
|
||||
|
||||
milestone = create :milestone,
|
||||
title: "GL-113",
|
||||
project: project,
|
||||
due_date: '2114-08-20',
|
||||
description: 'Lorem Ipsum is simply dummy text'
|
||||
|
||||
create :issue,
|
||||
project: project,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,20 +3,11 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
|
|||
include SharedPaths
|
||||
include SharedGroup
|
||||
include SharedUser
|
||||
include Select2Helper
|
||||
|
||||
step 'I should see back to dashboard button' do
|
||||
expect(page).to have_content 'Go to dashboard'
|
||||
end
|
||||
|
||||
step 'gitlab user "Mike"' do
|
||||
create(:user, name: "Mike")
|
||||
end
|
||||
|
||||
step 'I click link "Add members"' do
|
||||
find(:css, 'button.btn-new').click
|
||||
end
|
||||
|
||||
step 'I should see group "Owned"' do
|
||||
expect(page).to have_content '@owned'
|
||||
end
|
||||
|
@ -37,59 +28,6 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
|
|||
expect(page).to have_content 'Public-project'
|
||||
end
|
||||
|
||||
step 'I select "Mike" as "Reporter"' do
|
||||
user = User.find_by(name: "Mike")
|
||||
|
||||
page.within ".users-group-form" do
|
||||
select2(user.id, from: "#user_ids", multiple: true)
|
||||
select "Reporter", from: "access_level"
|
||||
end
|
||||
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I select "Mike" as "Master"' do
|
||||
user = User.find_by(name: "Mike")
|
||||
|
||||
page.within ".users-group-form" do
|
||||
select2(user.id, from: "#user_ids", multiple: true)
|
||||
select "Master", from: "access_level"
|
||||
end
|
||||
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I should see "Mike" in team list as "Reporter"' do
|
||||
page.within '.well-list' do
|
||||
expect(page).to have_content('Mike')
|
||||
expect(page).to have_content('Reporter')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see "Mike" in team list as "Owner"' do
|
||||
page.within '.well-list' do
|
||||
expect(page).to have_content('Mike')
|
||||
expect(page).to have_content('Owner')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I select "sjobs@apple.com" as "Reporter"' do
|
||||
page.within ".users-group-form" do
|
||||
select2("sjobs@apple.com", from: "#user_ids", multiple: true)
|
||||
select "Reporter", from: "access_level"
|
||||
end
|
||||
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do
|
||||
page.within '.well-list' do
|
||||
expect(page).to have_content('sjobs@apple.com')
|
||||
expect(page).to have_content('invited')
|
||||
expect(page).to have_content('Reporter')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see group "Owned" projects list' do
|
||||
owned_group.projects.each do |project|
|
||||
expect(page).to have_link project.name
|
||||
|
@ -112,36 +50,6 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
|
|||
end
|
||||
end
|
||||
|
||||
step 'I select user "Mary Jane" from list with role "Reporter"' do
|
||||
user = User.find_by(name: "Mary Jane") || create(:user, name: "Mary Jane")
|
||||
click_button 'Add members'
|
||||
page.within ".users-group-form" do
|
||||
select2(user.id, from: "#user_ids", multiple: true)
|
||||
select "Reporter", from: "access_level"
|
||||
end
|
||||
click_button "Add users to group"
|
||||
end
|
||||
|
||||
step 'I should see user "John Doe" in team list' do
|
||||
projects_with_access = find(".panel .well-list")
|
||||
expect(projects_with_access).to have_content("John Doe")
|
||||
end
|
||||
|
||||
step 'I should not see user "John Doe" in team list' do
|
||||
projects_with_access = find(".panel .well-list")
|
||||
expect(projects_with_access).not_to have_content("John Doe")
|
||||
end
|
||||
|
||||
step 'I should see user "Mary Jane" in team list' do
|
||||
projects_with_access = find(".panel .well-list")
|
||||
expect(projects_with_access).to have_content("Mary Jane")
|
||||
end
|
||||
|
||||
step 'I should not see user "Mary Jane" in team list' do
|
||||
projects_with_access = find(".panel .well-list")
|
||||
expect(projects_with_access).not_to have_content("Mary Jane")
|
||||
end
|
||||
|
||||
step 'project from group "Owned" has issues assigned to me' do
|
||||
create :issue,
|
||||
project: project,
|
||||
|
@ -203,67 +111,6 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
|
|||
expect(page).not_to have_link("Remove avatar")
|
||||
end
|
||||
|
||||
step 'I click on the "Remove User From Group" button for "John Doe"' do
|
||||
find(:css, 'li', text: "John Doe").find(:css, 'a.btn-remove').click
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I click on the "Remove User From Group" button for "Mary Jane"' do
|
||||
find(:css, 'li', text: "Mary Jane").find(:css, 'a.btn-remove').click
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I should not see the "Remove User From Group" button for "John Doe"' do
|
||||
expect(find(:css, 'li', text: "John Doe")).not_to have_selector(:css, 'a.btn-remove')
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I should not see the "Remove User From Group" button for "Mary Jane"' do
|
||||
expect(find(:css, 'li', text: "Mary Jane")).not_to have_selector(:css, 'a.btn-remove')
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I search for \'Mary\' member' do
|
||||
page.within '.member-search-form' do
|
||||
fill_in 'search', with: 'Mary'
|
||||
click_button 'Search'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I click on group milestones' do
|
||||
click_link 'Milestones'
|
||||
end
|
||||
|
||||
step 'I should see group milestones index page has no milestones' do
|
||||
expect(page).to have_content('No milestones to show')
|
||||
end
|
||||
|
||||
step 'Group has projects with milestones' do
|
||||
group_milestone
|
||||
end
|
||||
|
||||
step 'I should see group milestones index page with milestones' do
|
||||
expect(page).to have_content('Version 7.2')
|
||||
expect(page).to have_content('GL-113')
|
||||
expect(page).to have_link('2 Issues', href: issues_group_path("owned", milestone_title: "Version 7.2"))
|
||||
expect(page).to have_link('3 Merge Requests', href: merge_requests_group_path("owned", milestone_title: "GL-113"))
|
||||
end
|
||||
|
||||
step 'I click on one group milestone' do
|
||||
click_link 'GL-113'
|
||||
end
|
||||
|
||||
step 'I should see group milestone with descriptions and expiry date' do
|
||||
expect(page).to have_content('expires at Aug 20, 2114')
|
||||
end
|
||||
|
||||
step 'I should see group milestone with all issues and MRs assigned to that milestone' do
|
||||
expect(page).to have_content('Milestone GL-113')
|
||||
expect(page).to have_content('Progress: 0 closed – 4 open')
|
||||
expect(page).to have_link(@issue1.title, href: namespace_project_issue_path(@project1.namespace, @project1, @issue1))
|
||||
expect(page).to have_link(@mr3.title, href: namespace_project_merge_request_path(@project3.namespace, @project3, @mr3))
|
||||
end
|
||||
|
||||
step 'Group "Owned" has archived project' do
|
||||
group = Group.find_by(name: 'Owned')
|
||||
create(:project, namespace: group, archived: true, path: "archived-project")
|
||||
|
@ -273,60 +120,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
|
|||
expect(page).to have_xpath("//span[@class='label label-warning']", text: 'archived')
|
||||
end
|
||||
|
||||
step 'I fill milestone name' do
|
||||
fill_in 'milestone_title', with: 'v2.9.0'
|
||||
end
|
||||
|
||||
step 'I click new milestone button' do
|
||||
click_link "New Milestone"
|
||||
end
|
||||
|
||||
step 'I press create mileston button' do
|
||||
click_button "Create Milestone"
|
||||
end
|
||||
|
||||
step 'milestone in each project should be created' do
|
||||
group = Group.find_by(name: 'Owned')
|
||||
expect(page).to have_content "Milestone v2.9.0"
|
||||
expect(group.projects).to be_present
|
||||
|
||||
group.projects.each do |project|
|
||||
expect(page).to have_content project.name
|
||||
end
|
||||
end
|
||||
|
||||
step 'I change the "Mary Jane" role to "Developer"' do
|
||||
member = mary_jane_member
|
||||
|
||||
page.within "#group_member_#{member.id}" do
|
||||
find(".js-toggle-button").click
|
||||
page.within "#edit_group_member_#{member.id}" do
|
||||
select 'Developer', from: 'group_member_access_level'
|
||||
click_on 'Save'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see "Mary Jane" as "Developer"' do
|
||||
member = mary_jane_member
|
||||
|
||||
page.within "#group_member_#{member.id}" do
|
||||
page.within '.member-access-level' do
|
||||
expect(page).to have_content "Developer"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def owned_group
|
||||
@owned_group ||= Group.find_by(name: "Owned")
|
||||
end
|
||||
|
||||
def mary_jane_member
|
||||
user = User.find_by(name: "Mary Jane")
|
||||
owned_group.members.find_by(user_id: user.id)
|
||||
end
|
||||
private
|
||||
|
||||
def assigned_to_me(key)
|
||||
project.send(key).where(assignee_id: current_user.id)
|
||||
|
@ -335,70 +129,4 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
|
|||
def project
|
||||
owned_group.projects.first
|
||||
end
|
||||
|
||||
def group_milestone
|
||||
group = owned_group
|
||||
|
||||
@project1 = create :project,
|
||||
group: group
|
||||
project2 = create :project,
|
||||
path: 'gitlab-ci',
|
||||
group: group
|
||||
@project3 = create :project,
|
||||
path: 'cookbook-gitlab',
|
||||
group: group
|
||||
milestone1_project1 = create :milestone,
|
||||
title: "Version 7.2",
|
||||
project: @project1
|
||||
milestone1_project2 = create :milestone,
|
||||
title: "Version 7.2",
|
||||
project: project2
|
||||
create :milestone,
|
||||
title: "Version 7.2",
|
||||
project: @project3
|
||||
milestone2_project1 = create :milestone,
|
||||
title: "GL-113",
|
||||
project: @project1
|
||||
milestone2_project2 = create :milestone,
|
||||
title: "GL-113",
|
||||
project: project2
|
||||
milestone2_project3 = create :milestone,
|
||||
title: "GL-113",
|
||||
project: @project3,
|
||||
due_date: '2114-08-20',
|
||||
description: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry'
|
||||
@issue1 = create :issue,
|
||||
project: @project1,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone2_project1
|
||||
create :issue,
|
||||
project: project2,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone1_project2
|
||||
create :issue,
|
||||
project: @project3,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone1_project1
|
||||
create :merge_request,
|
||||
source_project: @project1,
|
||||
target_project: @project1,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone2_project1
|
||||
create :merge_request,
|
||||
source_project: project2,
|
||||
target_project: project2,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone2_project2
|
||||
@mr3 = create :merge_request,
|
||||
source_project: @project3,
|
||||
target_project: @project3,
|
||||
assignee: current_user,
|
||||
author: current_user,
|
||||
milestone: milestone2_project3
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,10 +15,6 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps
|
|||
expect(page).to have_content(user.username)
|
||||
end
|
||||
|
||||
step 'I click link "Add members"' do
|
||||
find(:css, 'button.btn-new').click
|
||||
end
|
||||
|
||||
step 'I select "Mike" as "Reporter"' do
|
||||
user = User.find_by(name: "Mike")
|
||||
|
||||
|
|
|
@ -41,4 +41,8 @@ module SharedGroup
|
|||
project.team << [user, :master]
|
||||
@project_count += 1
|
||||
end
|
||||
|
||||
def owned_group
|
||||
@owned_group ||= Group.find_by(name: "Owned")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,10 @@ module SharedUser
|
|||
user_exists("Mary Jane", { username: "mary_jane" })
|
||||
end
|
||||
|
||||
step 'gitlab user "Mike"' do
|
||||
create(:user, name: "Mike")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def user_exists(name, options = {})
|
||||
|
|
Loading…
Reference in a new issue