Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
d38e69c6
Commit
d38e69c6
authored
Dec 16, 2014
by
Braden MacDonald
Committed by
E. Kolpakov
Jan 12, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Acceptance & Jasmine tests for library permissions editor
parent
93bb1f58
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
563 additions
and
5 deletions
+563
-5
cms/static/coffee/spec/main.coffee
+1
-0
cms/static/js/spec/views/pages/library_users_spec.js
+78
-0
cms/templates/js/mock/mock-manage-users-lib.underscore
+146
-0
common/djangoapps/student/views.py
+7
-3
common/test/acceptance/pages/studio/auto_auth.py
+5
-2
common/test/acceptance/pages/studio/users.py
+189
-0
common/test/acceptance/tests/studio/test_studio_library.py
+137
-0
No files found.
cms/static/coffee/spec/main.coffee
View file @
d38e69c6
...
...
@@ -256,6 +256,7 @@ define([
"js/spec/views/pages/course_outline_spec"
,
"js/spec/views/pages/course_rerun_spec"
,
"js/spec/views/pages/index_spec"
,
"js/spec/views/pages/library_users_spec"
,
"js/spec/views/modals/base_modal_spec"
,
"js/spec/views/modals/edit_xblock_spec"
,
...
...
cms/static/js/spec/views/pages/library_users_spec.js
0 → 100644
View file @
d38e69c6
define
([
"jquery"
,
"js/common_helpers/ajax_helpers"
,
"js/spec_helpers/view_helpers"
,
"js/factories/manage_users_lib"
,
"js/views/utils/view_utils"
],
function
(
$
,
AjaxHelpers
,
ViewHelpers
,
ManageUsersFactory
,
ViewUtils
)
{
"use strict"
;
describe
(
"Library Instructor Access Page"
,
function
()
{
var
mockHTML
=
readFixtures
(
'mock/mock-manage-users-lib.underscore'
);
beforeEach
(
function
()
{
ViewHelpers
.
installMockAnalytics
();
appendSetFixtures
(
mockHTML
);
ManageUsersFactory
(
"Mock Library"
,
[
"honor@example.com"
,
"audit@example.com"
,
"staff@example.com"
],
"dummy_change_role_url"
);
});
afterEach
(
function
()
{
ViewHelpers
.
removeMockAnalytics
();
});
it
(
"can give a user permission to use the library"
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
reloadSpy
=
spyOn
(
ViewUtils
,
'reload'
);
$
(
'.create-user-button'
).
click
();
expect
(
$
(
'.wrapper-create-user'
)).
toHaveClass
(
'is-shown'
);
$
(
'.user-email-input'
).
val
(
'other@example.com'
);
$
(
'.form-create.create-user .action-primary'
).
click
();
AjaxHelpers
.
expectJsonRequest
(
requests
,
'POST'
,
'dummy_change_role_url'
,
{
role
:
'library_user'
});
AjaxHelpers
.
respondWithJson
(
requests
,
{
'result'
:
'ok'
});
expect
(
reloadSpy
).
toHaveBeenCalled
();
});
it
(
"can cancel adding a user to the library"
,
function
()
{
$
(
'.create-user-button'
).
click
();
$
(
'.form-create.create-user .action-secondary'
).
click
();
expect
(
$
(
'.wrapper-create-user'
)).
not
.
toHaveClass
(
'is-shown'
);
});
it
(
"displays an error when the required field is blank"
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
$
(
'.create-user-button'
).
click
();
$
(
'.user-email-input'
).
val
(
''
);
var
errorPromptSelector
=
'.wrapper-prompt.is-shown .prompt.error'
;
expect
(
$
(
errorPromptSelector
).
length
).
toEqual
(
0
);
$
(
'.form-create.create-user .action-primary'
).
click
();
expect
(
$
(
errorPromptSelector
).
length
).
toEqual
(
1
);
expect
(
$
(
errorPromptSelector
)).
toContainText
(
'You must enter a valid email address'
);
expect
(
requests
.
length
).
toEqual
(
0
);
});
it
(
"displays an error when the user has already been added"
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
$
(
'.create-user-button'
).
click
();
$
(
'.user-email-input'
).
val
(
'honor@example.com'
);
var
warningPromptSelector
=
'.wrapper-prompt.is-shown .prompt.warning'
;
expect
(
$
(
warningPromptSelector
).
length
).
toEqual
(
0
);
$
(
'.form-create.create-user .action-primary'
).
click
();
expect
(
$
(
warningPromptSelector
).
length
).
toEqual
(
1
);
expect
(
$
(
warningPromptSelector
)).
toContainText
(
'Already a library team member'
);
expect
(
requests
.
length
).
toEqual
(
0
);
});
it
(
"can remove a user's permission to access the library"
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
reloadSpy
=
spyOn
(
ViewUtils
,
'reload'
);
$
(
'.user-item[data-email="honor@example.com"] .action-delete .delete'
).
click
();
expect
(
$
(
'.wrapper-prompt.is-shown .prompt.warning'
).
length
).
toEqual
(
1
);
$
(
'.wrapper-prompt.is-shown .action-primary'
).
click
();
AjaxHelpers
.
expectJsonRequest
(
requests
,
'DELETE'
,
'dummy_change_role_url'
,
{
role
:
null
});
AjaxHelpers
.
respondWithJson
(
requests
,
{
'result'
:
'ok'
});
expect
(
reloadSpy
).
toHaveBeenCalled
();
});
});
});
cms/templates/js/mock/mock-manage-users-lib.underscore
0 → 100644
View file @
d38e69c6
<div class="wrapper-mast wrapper">
<header class="mast has-actions has-subtitle">
<h1 class="page-header">
<small class="subtitle">Settings</small>
<span class="sr">> </span>Instructor Access
</h1>
<nav class="nav-actions">
<h3 class="sr">Page Actions</h3>
<ul>
<li class="nav-item">
<a href="#" class="button new-button create-user-button"><i class="icon-plus"></i> Add Instructor</a>
</li>
</ul>
</nav>
</header>
</div>
<div class="wrapper-content wrapper">
<section class="content">
<article class="content-primary" role="main">
<div class="wrapper-create-element animate wrapper-create-user">
<form class="form-create create-user" id="create-user-form" name="create-user-form">
<div class="wrapper-form">
<h3 class="title">Grant Instructor Access to This Library</h3>
<fieldset class="form-fields">
<legend class="sr">New Instructor Information</legend>
<ol class="list-input">
<li class="field text required create-user-email">
<label for="user-email-input">User's Email Address</label>
<input id="user-email-input" class="user-email-input" name="user-email" type="text" placeholder="example: username@domain.com" value="">
<span class="tip tip-stacked">Please provide the email address of the instructor you'd like to add</span>
</li>
</ol>
</fieldset>
</div>
<div class="actions">
<button class="action action-primary" type="submit">Add User</button>
<button class="action action-secondary action-cancel">Cancel</button>
</div>
</form>
</div>
<ol class="user-list">
<li class="user-item" data-email="honor@example.com">
<span class="wrapper-ui-badge">
<span class="flag flag-role flag-role-staff is-hanging">
<span class="label sr">Current Role:</span>
<span class="value">
Staff
</span>
</span>
</span>
<div class="item-metadata">
<h3 class="user-name">
<span class="user-username">honor</span>
<span class="user-email">
<a class="action action-email" href="mailto:honor@example.com" title="send an email message to honor@example.com">honor@example.com</a>
</span>
</h3>
</div>
<ul class="item-actions user-actions">
<li class="action action-role">
<a href="#" class="make-instructor admin-role add-admin-role">Add Admin Access</span></a>
<a href="#" class="make-user admin-role remove-admin-role">Remove Staff Access</span></a>
</li>
<li class="action action-delete ">
<a href="#" class="delete remove-user action-icon" data-tooltip="Remove this user"><i class="icon-trash"></i><span class="sr">Delete the user, honor</span></a>
</li>
</ul>
</li>
<li class="user-item" data-email="audit@example.com">
<span class="wrapper-ui-badge">
<span class="flag flag-role flag-role-admin is-hanging">
<span class="label sr">Current Role:</span>
<span class="value">
Admin
</span>
</span>
</span>
<div class="item-metadata">
<h3 class="user-name">
<span class="user-username">audit</span>
<span class="user-email">
<a class="action action-email" href="mailto:audit@example.com" title="send an email message to audit@example.com">audit@example.com</a>
</span>
</h3>
</div>
<ul class="item-actions user-actions">
<li class="action action-role">
<a href="#" class="make-staff admin-role remove-admin-role">Remove Admin Access</span></a>
</li>
<li class="action action-delete ">
<a href="#" class="delete remove-user action-icon" data-tooltip="Remove this user"><i class="icon-trash"></i><span class="sr">Delete the user, audit</span></a>
</li>
</ul>
</li>
<li class="user-item" data-email="staff@example.com">
<span class="wrapper-ui-badge">
<span class="flag flag-role flag-role-user is-hanging">
<span class="label sr">Current Role:</span>
<span class="value">
User
</span>
</span>
</span>
<div class="item-metadata">
<h3 class="user-name">
<span class="user-username">staff</span>
<span class="user-email">
<a class="action action-email" href="mailto:staff@example.com" title="send an email message to staff@example.com">staff@example.com</a>
</span>
</h3>
</div>
<ul class="item-actions user-actions">
<li class="action action-role">
<a href="#" class="make-staff admin-role add-admin-role">Add Staff Access</span></a>
</li>
<li class="action action-delete ">
<a href="#" class="delete remove-user action-icon" data-tooltip="Remove this user"><i class="icon-trash"></i><span class="sr">Delete the user, staff</span></a>
</li>
</ul>
</li>
</ol>
</article>
</section>
</div>
common/djangoapps/student/views.py
View file @
d38e69c6
...
...
@@ -1746,6 +1746,7 @@ def auto_auth(request):
* `staff`: Set to "true" to make the user global staff.
* `course_id`: Enroll the student in the course with `course_id`
* `roles`: Comma-separated list of roles to grant the student in the course with `course_id`
* `no_login`: Define this to create the user but not login
If username, email, or password are not provided, use
randomly generated credentials.
...
...
@@ -1765,6 +1766,7 @@ def auto_auth(request):
if
course_id
:
course_key
=
CourseLocator
.
from_string
(
course_id
)
role_names
=
[
v
.
strip
()
for
v
in
request
.
GET
.
get
(
'roles'
,
''
)
.
split
(
','
)
if
v
.
strip
()]
login_when_done
=
'no_login'
not
in
request
.
GET
# Get or create the user object
post_data
=
{
...
...
@@ -1808,14 +1810,16 @@ def auto_auth(request):
user
.
roles
.
add
(
role
)
# Log in as the user
user
=
authenticate
(
username
=
username
,
password
=
password
)
login
(
request
,
user
)
if
login_when_done
:
user
=
authenticate
(
username
=
username
,
password
=
password
)
login
(
request
,
user
)
create_comments_service_user
(
user
)
# Provide the user with a valid CSRF token
# then return a 200 response
success_msg
=
u"Logged in user {0} ({1}) with password {2} and user_id {3}"
.
format
(
success_msg
=
u"{} user {} ({}) with password {} and user_id {}"
.
format
(
u"Logged in"
if
login_when_done
else
"Created"
,
username
,
email
,
password
,
user
.
id
)
response
=
HttpResponse
(
success_msg
)
...
...
common/test/acceptance/pages/studio/auto_auth.py
View file @
d38e69c6
...
...
@@ -15,7 +15,7 @@ class AutoAuthPage(PageObject):
this url will create a user and log them in.
"""
def
__init__
(
self
,
browser
,
username
=
None
,
email
=
None
,
password
=
None
,
staff
=
None
,
course_id
=
None
,
roles
=
None
):
def
__init__
(
self
,
browser
,
username
=
None
,
email
=
None
,
password
=
None
,
staff
=
None
,
course_id
=
None
,
roles
=
None
,
no_login
=
None
):
"""
Auto-auth is an end-point for HTTP GET requests.
By default, it will create accounts with random user credentials,
...
...
@@ -51,6 +51,9 @@ class AutoAuthPage(PageObject):
if
roles
is
not
None
:
self
.
_params
[
'roles'
]
=
roles
if
no_login
:
self
.
_params
[
'no_login'
]
=
True
@property
def
url
(
self
):
"""
...
...
@@ -66,7 +69,7 @@ class AutoAuthPage(PageObject):
def
is_browser_on_page
(
self
):
message
=
self
.
q
(
css
=
'BODY'
)
.
text
[
0
]
match
=
re
.
search
(
r'
Logged in
user ([^$]+) with password ([^$]+) and user_id ([^$]+)$'
,
message
)
match
=
re
.
search
(
r'
(Logged in|Created)
user ([^$]+) with password ([^$]+) and user_id ([^$]+)$'
,
message
)
return
True
if
match
else
False
def
get_user_id
(
self
):
...
...
common/test/acceptance/pages/studio/users.py
0 → 100644
View file @
d38e69c6
"""
Page classes to test either the Course Team page or the Library Team page.
"""
from
bok_choy.promise
import
EmptyPromise
from
bok_choy.page_object
import
PageObject
from
...tests.helpers
import
disable_animations
from
.
import
BASE_URL
def
wait_for_ajax_or_reload
(
browser
):
"""
Wait for all ajax requests to finish, OR for the page to reload.
Normal wait_for_ajax() chokes on occasion if the pages reloads,
giving "WebDriverException: Message: u'jQuery is not defined'"
"""
def
_is_ajax_finished
():
""" Wait for jQuery to finish all AJAX calls, if it is present. """
return
browser
.
execute_script
(
"return typeof(jQuery) == 'undefined' || jQuery.active == 0"
)
EmptyPromise
(
_is_ajax_finished
,
"Finished waiting for ajax requests."
)
.
fulfill
()
class
UsersPage
(
PageObject
):
"""
Base class for either the Course Team page or the Library Team page
"""
def
__init__
(
self
,
browser
,
locator
):
super
(
UsersPage
,
self
)
.
__init__
(
browser
)
self
.
locator
=
locator
@property
def
url
(
self
):
"""
URL to this page - override in subclass
"""
raise
NotImplementedError
def
is_browser_on_page
(
self
):
"""
Returns True iff the browser has loaded the page.
"""
return
self
.
q
(
css
=
'body.view-team'
)
.
present
@property
def
users
(
self
):
"""
Return a list of users listed on this page.
"""
return
self
.
q
(
css
=
'.user-list .user-item'
)
.
map
(
lambda
el
:
UserWrapper
(
self
.
browser
,
el
.
get_attribute
(
'data-email'
)))
.
results
@property
def
has_add_button
(
self
):
"""
Is the "New Team Member" button present?
"""
return
self
.
q
(
css
=
'.create-user-button'
)
.
present
def
click_add_button
(
self
):
"""
Click on the "New Team Member" button
"""
self
.
q
(
css
=
'.create-user-button'
)
.
click
()
@property
def
new_user_form_visible
(
self
):
""" Is the new user form visible? """
return
self
.
q
(
css
=
'.form-create.create-user .user-email-input'
)
.
visible
def
set_new_user_email
(
self
,
email
):
""" Set the value of the "New User Email Address" field. """
self
.
q
(
css
=
'.form-create.create-user .user-email-input'
)
.
fill
(
email
)
def
click_submit_new_user_form
(
self
):
""" Submit the "New User" form """
self
.
q
(
css
=
'.form-create.create-user .action-primary'
)
.
click
()
wait_for_ajax_or_reload
(
self
.
browser
)
class
LibraryUsersPage
(
UsersPage
):
"""
Library Team page in Studio
"""
@property
def
url
(
self
):
"""
URL to the "User Access" page for the given library.
"""
return
"{}/library/{}/team/"
.
format
(
BASE_URL
,
unicode
(
self
.
locator
))
class
UserWrapper
(
PageObject
):
"""
A PageObject representing a wrapper around a user listed on the course/library team page.
"""
url
=
None
COMPONENT_BUTTONS
=
{
'basic_tab'
:
'.editor-tabs li.inner_tab_wrap:nth-child(1) > a'
,
'advanced_tab'
:
'.editor-tabs li.inner_tab_wrap:nth-child(2) > a'
,
'save_settings'
:
'.action-save'
,
}
def
__init__
(
self
,
browser
,
email
):
super
(
UserWrapper
,
self
)
.
__init__
(
browser
)
self
.
email
=
email
self
.
selector
=
'.user-list .user-item[data-email="{}"]'
.
format
(
self
.
email
)
def
is_browser_on_page
(
self
):
"""
Sanity check that our wrapper element is on the page.
"""
return
self
.
q
(
css
=
self
.
selector
)
.
present
def
_bounded_selector
(
self
,
selector
):
"""
Return `selector`, but limited to this particular user entry's context
"""
return
'{} {}'
.
format
(
self
.
selector
,
selector
)
@property
def
name
(
self
):
""" Get this user's username, as displayed. """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.user-username'
))
.
text
[
0
]
@property
def
role_label
(
self
):
""" Get this user's role, as displayed. """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.flag-role .value'
))
.
text
[
0
]
@property
def
is_current_user
(
self
):
""" Does the UI indicate that this is the current user? """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.flag-role .msg-you'
))
.
present
@property
def
can_promote
(
self
):
""" Can this user be promoted to a more powerful role? """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.add-admin-role'
))
.
present
@property
def
promote_button_text
(
self
):
""" What does the promote user button say? """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.add-admin-role'
))
.
text
[
0
]
def
click_promote
(
self
):
""" Click on the button to promote this user to the more powerful role """
self
.
q
(
css
=
self
.
_bounded_selector
(
'.add-admin-role'
))
.
click
()
wait_for_ajax_or_reload
(
self
.
browser
)
@property
def
can_demote
(
self
):
""" Can this user be demoted to a less powerful role? """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.remove-admin-role'
))
.
present
@property
def
demote_button_text
(
self
):
""" What does the demote user button say? """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.remove-admin-role'
))
.
text
[
0
]
def
click_demote
(
self
):
""" Click on the button to demote this user to the less powerful role """
self
.
q
(
css
=
self
.
_bounded_selector
(
'.remove-admin-role'
))
.
click
()
wait_for_ajax_or_reload
(
self
.
browser
)
@property
def
can_delete
(
self
):
""" Can this user be deleted? """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.action-delete:not(.is-disabled) .remove-user'
))
.
present
def
click_delete
(
self
):
""" Click the button to delete this user. """
disable_animations
(
self
)
self
.
q
(
css
=
self
.
_bounded_selector
(
'.remove-user'
))
.
click
()
# We can't use confirm_prompt because its wait_for_ajax is flaky when the page is expected to reload.
self
.
wait_for_element_visibility
(
'.prompt'
,
'Prompt is visible'
)
self
.
wait_for_element_visibility
(
'.prompt .action-primary'
,
'Confirmation button is visible'
)
self
.
q
(
css
=
'.prompt .action-primary'
)
.
click
()
wait_for_ajax_or_reload
(
self
.
browser
)
@property
def
has_no_change_warning
(
self
):
""" Does this have a warning in place of the promote/demote buttons? """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.notoggleforyou'
))
.
present
@property
def
no_change_warning_text
(
self
):
""" Text of the warning seen in place of the promote/demote buttons. """
return
self
.
q
(
css
=
self
.
_bounded_selector
(
'.notoggleforyou'
))
.
text
[
0
]
common/test/acceptance/tests/studio/test_studio_library.py
View file @
d38e69c6
...
...
@@ -5,8 +5,10 @@ from ddt import ddt, data
from
.base_studio_test
import
StudioLibraryTest
from
...fixtures.course
import
XBlockFixtureDesc
from
...pages.studio.auto_auth
import
AutoAuthPage
from
...pages.studio.utils
import
add_component
from
...pages.studio.library
import
LibraryPage
from
...pages.studio.users
import
LibraryUsersPage
@ddt
...
...
@@ -306,3 +308,138 @@ class LibraryNavigationTest(StudioLibraryTest):
self
.
assertEqual
(
self
.
lib_page
.
xblocks
[
0
]
.
name
,
'1'
)
self
.
assertEqual
(
self
.
lib_page
.
xblocks
[
-
1
]
.
name
,
'11'
)
self
.
assertEqual
(
self
.
lib_page
.
get_page_number
(),
'1'
)
class
LibraryUsersPageTest
(
StudioLibraryTest
):
"""
Test the functionality of the library "Instructor Access" page.
"""
def
setUp
(
self
):
super
(
LibraryUsersPageTest
,
self
)
.
setUp
()
# Create a second user for use in these tests:
AutoAuthPage
(
self
.
browser
,
username
=
"second"
,
email
=
"second@example.com"
,
no_login
=
True
)
.
visit
()
self
.
page
=
LibraryUsersPage
(
self
.
browser
,
self
.
library_key
)
self
.
page
.
visit
()
def
_expect_refresh
(
self
):
"""
Wait for the page to reload.
"""
self
.
page
=
LibraryUsersPage
(
self
.
browser
,
self
.
library_key
)
.
wait_for_page
()
def
test_user_management
(
self
):
"""
Scenario: Ensure that we can edit the permissions of users.
Given I have a library in Studio where I am the only admin
assigned (which is the default for a newly-created library)
And I navigate to Library "Instructor Access" Page in Studio
Then there should be one user listed (myself), and I must
not be able to remove myself or my instructor privilege.
When I click Add Intructor
Then I see a form to complete
When I complete the form and submit it
Then I can see the new user is listed as a "User" of the library
When I click to Add Staff permissions to the new user
Then I can see the new user has staff permissions and that I am now
able to promote them to an Admin or remove their staff permissions.
When I click to Add Admin permissions to the new user
Then I can see the new user has admin permissions and that I can now
remove Admin permissions from either user.
"""
def
check_is_only_admin
(
user
):
"""
Ensure user is an admin user and cannot be removed.
(There must always be at least one admin user.)
"""
self
.
assertIn
(
"admin"
,
user
.
role_label
.
lower
())
self
.
assertFalse
(
user
.
can_promote
)
self
.
assertFalse
(
user
.
can_demote
)
self
.
assertFalse
(
user
.
can_delete
)
self
.
assertTrue
(
user
.
has_no_change_warning
)
self
.
assertIn
(
"Promote another member to Admin to remove admin rights"
,
user
.
no_change_warning_text
)
self
.
assertEqual
(
len
(
self
.
page
.
users
),
1
)
user
=
self
.
page
.
users
[
0
]
self
.
assertTrue
(
user
.
is_current_user
)
check_is_only_admin
(
user
)
# Add a new user:
self
.
assertTrue
(
self
.
page
.
has_add_button
)
self
.
assertFalse
(
self
.
page
.
new_user_form_visible
)
self
.
page
.
click_add_button
()
self
.
assertTrue
(
self
.
page
.
new_user_form_visible
)
self
.
page
.
set_new_user_email
(
'second@example.com'
)
self
.
page
.
click_submit_new_user_form
()
# Check the new user's listing:
def
get_two_users
():
"""
Expect two users to be listed, one being me, and another user.
Returns me, them
"""
users
=
self
.
page
.
users
self
.
assertEqual
(
len
(
users
),
2
)
self
.
assertEqual
(
len
([
u
for
u
in
users
if
u
.
is_current_user
]),
1
)
if
users
[
0
]
.
is_current_user
:
return
users
[
0
],
users
[
1
]
else
:
return
users
[
1
],
users
[
0
]
self
.
_expect_refresh
()
user_me
,
them
=
get_two_users
()
check_is_only_admin
(
user_me
)
self
.
assertIn
(
"user"
,
them
.
role_label
.
lower
())
self
.
assertTrue
(
them
.
can_promote
)
self
.
assertIn
(
"Add Staff Access"
,
them
.
promote_button_text
)
self
.
assertFalse
(
them
.
can_demote
)
self
.
assertTrue
(
them
.
can_delete
)
self
.
assertFalse
(
them
.
has_no_change_warning
)
# Add Staff permissions to the new user:
them
.
click_promote
()
self
.
_expect_refresh
()
user_me
,
them
=
get_two_users
()
check_is_only_admin
(
user_me
)
self
.
assertIn
(
"staff"
,
them
.
role_label
.
lower
())
self
.
assertTrue
(
them
.
can_promote
)
self
.
assertIn
(
"Add Admin Access"
,
them
.
promote_button_text
)
self
.
assertTrue
(
them
.
can_demote
)
self
.
assertIn
(
"Remove Staff Access"
,
them
.
demote_button_text
)
self
.
assertTrue
(
them
.
can_delete
)
self
.
assertFalse
(
them
.
has_no_change_warning
)
# Add Admin permissions to the new user:
them
.
click_promote
()
self
.
_expect_refresh
()
user_me
,
them
=
get_two_users
()
self
.
assertIn
(
"admin"
,
user_me
.
role_label
.
lower
())
self
.
assertFalse
(
user_me
.
can_promote
)
self
.
assertTrue
(
user_me
.
can_demote
)
self
.
assertTrue
(
user_me
.
can_delete
)
self
.
assertFalse
(
user_me
.
has_no_change_warning
)
self
.
assertIn
(
"admin"
,
them
.
role_label
.
lower
())
self
.
assertFalse
(
them
.
can_promote
)
self
.
assertTrue
(
them
.
can_demote
)
self
.
assertIn
(
"Remove Admin Access"
,
them
.
demote_button_text
)
self
.
assertTrue
(
them
.
can_delete
)
self
.
assertFalse
(
them
.
has_no_change_warning
)
# Delete the new user:
them
.
click_delete
()
self
.
_expect_refresh
()
self
.
assertEqual
(
len
(
self
.
page
.
users
),
1
)
user
=
self
.
page
.
users
[
0
]
self
.
assertTrue
(
user
.
is_current_user
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment