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
deacfebd
Commit
deacfebd
authored
Sep 04, 2015
by
Diana Huang
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9607 from edx/diana/teams-event-tracking
Add teams eventing and tests.
parents
d567e5e3
a743f4a6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
137 additions
and
10 deletions
+137
-10
common/test/acceptance/tests/lms/test_teams.py
+50
-6
lms/djangoapps/teams/tests/test_views.py
+55
-4
lms/djangoapps/teams/views.py
+32
-0
No files found.
common/test/acceptance/tests/lms/test_teams.py
View file @
deacfebd
...
...
@@ -11,7 +11,7 @@ from flaky import flaky
from
nose.plugins.attrib
import
attr
from
uuid
import
uuid4
from
..helpers
import
UniqueCourseTest
from
..helpers
import
UniqueCourseTest
,
EventsTestMixin
from
...fixtures
import
LMS_BASE_URL
from
...fixtures.course
import
CourseFixture
from
...fixtures.discussion
import
(
...
...
@@ -28,7 +28,7 @@ from ...pages.lms.teams import TeamsPage, MyTeamsPage, BrowseTopicsPage, BrowseT
TOPICS_PER_PAGE
=
12
class
TeamsTabBase
(
UniqueCourseTest
):
class
TeamsTabBase
(
EventsTestMixin
,
UniqueCourseTest
):
"""Base class for Teams Tab tests"""
def
setUp
(
self
):
super
(
TeamsTabBase
,
self
)
.
setUp
()
...
...
@@ -123,6 +123,10 @@ class TeamsTabBase(UniqueCourseTest):
# We are doing these operations on this top-level page object to avoid reloading the page.
self
.
teams_page
.
verify_my_team_count
(
expected_number_of_teams
)
def
only_team_events
(
self
,
event
):
"""Filter out all non-team events."""
return
event
[
'event_type'
]
.
startswith
(
'edx.team.'
)
@ddt.ddt
@attr
(
'shard_5'
)
...
...
@@ -899,7 +903,8 @@ class CreateTeamTest(TeamFormActions):
Then I should see the Create Team header and form
When I fill all the fields present with appropriate data
And I click Create button
Then I should see the page for my team
Then I expect analytics events to be emitted
And I should see the page for my team
And I should see the message that says "You are member of this team"
And the new team should be added to the list of teams within the topic
And the number of teams should be updated on the topic card
...
...
@@ -911,7 +916,24 @@ class CreateTeamTest(TeamFormActions):
self
.
verify_and_navigate_to_create_team_page
()
self
.
fill_create_or_edit_form
()
self
.
create_or_edit_team_page
.
submit_form
()
expected_events
=
[
{
'event_type'
:
'edx.team.created'
,
'event'
:
{
'course_id'
:
self
.
course_id
,
}
},
{
'event_type'
:
'edx.team.learner_added'
,
'event'
:
{
'course_id'
:
self
.
course_id
,
'add_method'
:
'added_on_create'
,
}
}
]
with
self
.
assert_events_match_during
(
event_filter
=
self
.
only_team_events
,
expected_events
=
expected_events
):
self
.
create_or_edit_team_page
.
submit_form
()
# Verify that the page is shown for the new team
team_page
=
TeamPage
(
self
.
browser
,
self
.
course_id
)
...
...
@@ -1330,6 +1352,7 @@ class TeamPageTest(TeamsTabBase):
And I should not see New Post button
When I click on Join Team button
Then there should be no Join Team button and no message
And an analytics event should be emitted
And I should see the updated information under Team Details
And I should see New Post button
And if I switch to "My Team", the team I have joined is displayed
...
...
@@ -1337,7 +1360,17 @@ class TeamPageTest(TeamsTabBase):
self
.
_set_team_configuration_and_membership
(
create_membership
=
False
)
self
.
team_page
.
visit
()
self
.
assertTrue
(
self
.
team_page
.
join_team_button_present
)
self
.
team_page
.
click_join_team_button
()
expected_events
=
[
{
'event_type'
:
'edx.team.learner_added'
,
'event'
:
{
'course_id'
:
self
.
course_id
,
'add_method'
:
'joined_from_team_view'
}
}
]
with
self
.
assert_events_match_during
(
event_filter
=
self
.
only_team_events
,
expected_events
=
expected_events
):
self
.
team_page
.
click_join_team_button
()
self
.
assertFalse
(
self
.
team_page
.
join_team_button_present
)
self
.
assertFalse
(
self
.
team_page
.
join_team_message_present
)
self
.
assert_team_details
(
num_members
=
1
,
is_member
=
True
)
...
...
@@ -1397,6 +1430,7 @@ class TeamPageTest(TeamsTabBase):
Then I should see Leave Team link
When I click on Leave Team link
Then user should be removed from team
And an analytics event should be emitted
And I should see Join Team button
And I should not see New Post button
And if I switch to "My Team", the team I have left is not displayed
...
...
@@ -1405,7 +1439,17 @@ class TeamPageTest(TeamsTabBase):
self
.
team_page
.
visit
()
self
.
assertFalse
(
self
.
team_page
.
join_team_button_present
)
self
.
assert_team_details
(
num_members
=
1
)
self
.
team_page
.
click_leave_team_link
()
expected_events
=
[
{
'event_type'
:
'edx.team.learner_removed'
,
'event'
:
{
'course_id'
:
self
.
course_id
,
'remove_method'
:
'self_removal'
}
}
]
with
self
.
assert_events_match_during
(
event_filter
=
self
.
only_team_events
,
expected_events
=
expected_events
):
self
.
team_page
.
click_leave_team_link
()
self
.
assert_team_details
(
num_members
=
0
,
is_member
=
False
)
self
.
assertTrue
(
self
.
team_page
.
join_team_button_present
)
...
...
lms/djangoapps/teams/tests/test_views.py
View file @
deacfebd
...
...
@@ -14,6 +14,7 @@ from rest_framework.test import APITestCase, APIClient
from
courseware.tests.factories
import
StaffFactory
from
common.test.utils
import
skip_signal
from
util.testing
import
EventTestMixin
from
student.tests.factories
import
UserFactory
,
AdminFactory
,
CourseEnrollmentFactory
from
student.models
import
CourseEnrollment
from
xmodule.modulestore.tests.django_utils
import
SharedModuleStoreTestCase
...
...
@@ -529,9 +530,12 @@ class TestListTeamsAPI(TeamAPITestCase):
@ddt.ddt
class
TestCreateTeamAPI
(
TeamAPITestCase
):
class
TestCreateTeamAPI
(
EventTestMixin
,
TeamAPITestCase
):
"""Test cases for the team creation endpoint."""
def
setUp
(
self
):
# pylint: disable=arguments-differ
super
(
TestCreateTeamAPI
,
self
)
.
setUp
(
'teams.views.tracker'
)
@ddt.data
(
(
None
,
401
),
(
'student_inactive'
,
401
),
...
...
@@ -549,11 +553,15 @@ class TestCreateTeamAPI(TeamAPITestCase):
teams
=
self
.
get_teams_list
(
user
=
user
)
self
.
assertIn
(
"New Team"
,
[
team
[
'name'
]
for
team
in
teams
[
'results'
]])
def
_expected_team_id
(
self
,
team
,
expected_prefix
):
""" Return the team id that we'd expect given this team data and this prefix. """
return
expected_prefix
+
'-'
+
team
[
'discussion_topic_id'
]
def
verify_expected_team_id
(
self
,
team
,
expected_prefix
):
""" Verifies that the team id starts with the specified prefix and ends with the discussion_topic_id """
self
.
assertIn
(
'id'
,
team
)
self
.
assertIn
(
'discussion_topic_id'
,
team
)
self
.
assertEqual
(
team
[
'id'
],
expected_prefix
+
'-'
+
team
[
'discussion_topic_id'
]
)
self
.
assertEqual
(
team
[
'id'
],
self
.
_expected_team_id
(
team
,
expected_prefix
)
)
def
test_naming
(
self
):
new_teams
=
[
...
...
@@ -640,6 +648,19 @@ class TestCreateTeamAPI(TeamAPITestCase):
self
.
verify_expected_team_id
(
team
,
'fully-specified-team'
)
del
team
[
'id'
]
self
.
assert_event_emitted
(
'edx.team.created'
,
team_id
=
self
.
_expected_team_id
(
team
,
'fully-specified-team'
),
course_id
=
unicode
(
self
.
test_course_1
.
id
),
)
self
.
assert_event_emitted
(
'edx.team.learner_added'
,
team_id
=
self
.
_expected_team_id
(
team
,
'fully-specified-team'
),
course_id
=
unicode
(
self
.
test_course_1
.
id
),
user_id
=
self
.
users
[
creator
]
.
id
,
add_method
=
'added_on_create'
)
# Remove date_created and discussion_topic_id because they change between test runs
del
team
[
'date_created'
]
del
team
[
'discussion_topic_id'
]
...
...
@@ -1026,9 +1047,12 @@ class TestListMembershipAPI(TeamAPITestCase):
@ddt.ddt
class
TestCreateMembershipAPI
(
TeamAPITestCase
):
class
TestCreateMembershipAPI
(
EventTestMixin
,
TeamAPITestCase
):
"""Test cases for the membership creation endpoint."""
def
setUp
(
self
):
# pylint: disable=arguments-differ
super
(
TestCreateMembershipAPI
,
self
)
.
setUp
(
'teams.views.tracker'
)
@ddt.data
(
(
None
,
401
),
(
'student_inactive'
,
401
),
...
...
@@ -1053,6 +1077,18 @@ class TestCreateMembershipAPI(TeamAPITestCase):
memberships
=
self
.
get_membership_list
(
200
,
{
'team_id'
:
self
.
solar_team
.
team_id
})
self
.
assertEqual
(
memberships
[
'count'
],
2
)
add_method
=
'joined_from_team_view'
if
user
==
'student_enrolled_not_on_team'
else
'added_by_another_user'
self
.
assert_event_emitted
(
'edx.team.learner_added'
,
team_id
=
self
.
solar_team
.
team_id
,
user_id
=
self
.
users
[
'student_enrolled_not_on_team'
]
.
id
,
course_id
=
unicode
(
self
.
solar_team
.
course_id
),
add_method
=
add_method
)
else
:
self
.
assert_no_events_were_emitted
()
def
test_no_username
(
self
):
response
=
self
.
post_create_membership
(
400
,
{
'team_id'
:
self
.
solar_team
.
team_id
})
self
.
assertIn
(
'username'
,
json
.
loads
(
response
.
content
)[
'field_errors'
])
...
...
@@ -1176,9 +1212,12 @@ class TestDetailMembershipAPI(TeamAPITestCase):
@ddt.ddt
class
TestDeleteMembershipAPI
(
TeamAPITestCase
):
class
TestDeleteMembershipAPI
(
EventTestMixin
,
TeamAPITestCase
):
"""Test cases for the membership deletion endpoint."""
def
setUp
(
self
):
# pylint: disable=arguments-differ
super
(
TestDeleteMembershipAPI
,
self
)
.
setUp
(
'teams.views.tracker'
)
@ddt.data
(
(
None
,
401
),
(
'student_inactive'
,
401
),
...
...
@@ -1198,6 +1237,18 @@ class TestDeleteMembershipAPI(TeamAPITestCase):
user
=
user
)
if
status
==
204
:
remove_method
=
'self_removal'
if
user
==
'student_enrolled'
else
'removed_by_admin'
self
.
assert_event_emitted
(
'edx.team.learner_removed'
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
solar_team
.
course_id
),
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
,
remove_method
=
remove_method
)
else
:
self
.
assert_no_events_were_emitted
()
def
test_bad_team
(
self
):
self
.
delete_membership
(
'no_such_team'
,
self
.
users
[
'student_enrolled'
]
.
username
,
404
)
...
...
lms/djangoapps/teams/views.py
View file @
deacfebd
...
...
@@ -34,6 +34,7 @@ from xmodule.modulestore.django import modulestore
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
eventtracking
import
tracker
from
courseware.courses
import
get_course_with_access
,
has_access
from
student.models
import
CourseEnrollment
,
CourseAccessRole
from
student.roles
import
CourseStaffRole
...
...
@@ -417,9 +418,22 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
else
:
team
=
serializer
.
save
()
tracker
.
emit
(
'edx.team.created'
,
{
'team_id'
:
team
.
team_id
,
'course_id'
:
unicode
(
course_id
)
})
if
not
team_administrator
:
# Add the creating user to the team.
team
.
add_user
(
request
.
user
)
tracker
.
emit
(
'edx.team.learner_added'
,
{
'team_id'
:
team
.
team_id
,
'user_id'
:
request
.
user
.
id
,
'course_id'
:
unicode
(
team
.
course_id
),
'add_method'
:
'added_on_create'
}
)
return
Response
(
CourseTeamSerializer
(
team
)
.
data
)
def
get_page
(
self
):
...
...
@@ -974,6 +988,15 @@ class MembershipListView(ExpandableFieldViewMixin, GenericAPIView):
try
:
membership
=
team
.
add_user
(
user
)
tracker
.
emit
(
'edx.team.learner_added'
,
{
'team_id'
:
team
.
team_id
,
'user_id'
:
user
.
id
,
'course_id'
:
unicode
(
team
.
course_id
),
'add_method'
:
'joined_from_team_view'
if
user
==
request
.
user
else
'added_by_another_user'
}
)
except
AlreadyOnTeamInCourse
:
return
Response
(
build_api_error
(
...
...
@@ -1100,6 +1123,15 @@ class MembershipDetailView(ExpandableFieldViewMixin, GenericAPIView):
if
has_team_api_access
(
request
.
user
,
team
.
course_id
,
access_username
=
username
):
membership
=
self
.
get_membership
(
username
,
team
)
membership
.
delete
()
tracker
.
emit
(
'edx.team.learner_removed'
,
{
'team_id'
:
team
.
team_id
,
'course_id'
:
unicode
(
team
.
course_id
),
'user_id'
:
membership
.
user
.
id
,
'remove_method'
:
'self_removal'
if
membership
.
user
==
request
.
user
else
'removed_by_admin'
}
)
return
Response
(
status
=
status
.
HTTP_204_NO_CONTENT
)
else
:
return
Response
(
status
=
status
.
HTTP_404_NOT_FOUND
)
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