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
222c3ba0
Commit
222c3ba0
authored
Sep 11, 2015
by
Diana Huang
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9713 from edx/diana/eventing-updates
Add course id contexts to teams events
parents
3613d0f0
f37ffc2f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
25 additions
and
44 deletions
+25
-44
common/test/acceptance/tests/lms/test_teams.py
+1
-15
lms/djangoapps/teams/tests/test_views.py
+0
-12
lms/djangoapps/teams/views.py
+24
-17
No files found.
common/test/acceptance/tests/lms/test_teams.py
View file @
222c3ba0
...
@@ -803,7 +803,6 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
...
@@ -803,7 +803,6 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
events
=
[{
events
=
[{
'event_type'
:
'edx.team.searched'
,
'event_type'
:
'edx.team.searched'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'search_text'
:
search_text
,
'search_text'
:
search_text
,
'topic_id'
:
self
.
topic
[
'id'
],
'topic_id'
:
self
.
topic
[
'id'
],
'number_of_results'
:
0
'number_of_results'
:
0
...
@@ -1043,15 +1042,11 @@ class CreateTeamTest(TeamFormActions):
...
@@ -1043,15 +1042,11 @@ class CreateTeamTest(TeamFormActions):
expected_events
=
[
expected_events
=
[
{
{
'event_type'
:
'edx.team.created'
,
'event_type'
:
'edx.team.created'
'event'
:
{
'course_id'
:
self
.
course_id
,
}
},
},
{
{
'event_type'
:
'edx.team.learner_added'
,
'event_type'
:
'edx.team.learner_added'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'add_method'
:
'added_on_create'
,
'add_method'
:
'added_on_create'
,
}
}
}
}
...
@@ -1209,14 +1204,12 @@ class DeleteTeamTest(TeamFormActions):
...
@@ -1209,14 +1204,12 @@ class DeleteTeamTest(TeamFormActions):
{
{
'event_type'
:
'edx.team.deleted'
,
'event_type'
:
'edx.team.deleted'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'team_id'
:
self
.
team
[
'id'
]
'team_id'
:
self
.
team
[
'id'
]
}
}
},
},
{
{
'event_type'
:
'edx.team.learner_removed'
,
'event_type'
:
'edx.team.learner_removed'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'team_id'
:
self
.
team
[
'id'
],
'team_id'
:
self
.
team
[
'id'
],
'remove_method'
:
'team_deleted'
,
'remove_method'
:
'team_deleted'
,
'user_id'
:
self
.
user_info
[
'user_id'
]
'user_id'
:
self
.
user_info
[
'user_id'
]
...
@@ -1302,7 +1295,6 @@ class EditTeamTest(TeamFormActions):
...
@@ -1302,7 +1295,6 @@ class EditTeamTest(TeamFormActions):
{
{
'event_type'
:
'edx.team.changed'
,
'event_type'
:
'edx.team.changed'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'team_id'
:
self
.
team
[
'id'
],
'team_id'
:
self
.
team
[
'id'
],
'field'
:
'country'
,
'field'
:
'country'
,
'old'
:
'AF'
,
'old'
:
'AF'
,
...
@@ -1313,7 +1305,6 @@ class EditTeamTest(TeamFormActions):
...
@@ -1313,7 +1305,6 @@ class EditTeamTest(TeamFormActions):
{
{
'event_type'
:
'edx.team.changed'
,
'event_type'
:
'edx.team.changed'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'team_id'
:
self
.
team
[
'id'
],
'team_id'
:
self
.
team
[
'id'
],
'field'
:
'name'
,
'field'
:
'name'
,
'old'
:
self
.
team
[
'name'
],
'old'
:
self
.
team
[
'name'
],
...
@@ -1324,7 +1315,6 @@ class EditTeamTest(TeamFormActions):
...
@@ -1324,7 +1315,6 @@ class EditTeamTest(TeamFormActions):
{
{
'event_type'
:
'edx.team.changed'
,
'event_type'
:
'edx.team.changed'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'team_id'
:
self
.
team
[
'id'
],
'team_id'
:
self
.
team
[
'id'
],
'field'
:
'language'
,
'field'
:
'language'
,
'old'
:
'aa'
,
'old'
:
'aa'
,
...
@@ -1335,7 +1325,6 @@ class EditTeamTest(TeamFormActions):
...
@@ -1335,7 +1325,6 @@ class EditTeamTest(TeamFormActions):
{
{
'event_type'
:
'edx.team.changed'
,
'event_type'
:
'edx.team.changed'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'team_id'
:
self
.
team
[
'id'
],
'team_id'
:
self
.
team
[
'id'
],
'field'
:
'description'
,
'field'
:
'description'
,
'old'
:
self
.
team
[
'description'
],
'old'
:
self
.
team
[
'description'
],
...
@@ -1515,7 +1504,6 @@ class EditMembershipTest(TeamFormActions):
...
@@ -1515,7 +1504,6 @@ class EditMembershipTest(TeamFormActions):
{
{
'event_type'
:
'edx.team.learner_removed'
,
'event_type'
:
'edx.team.learner_removed'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'team_id'
:
self
.
team
[
'id'
],
'team_id'
:
self
.
team
[
'id'
],
'remove_method'
:
'removed_by_admin'
,
'remove_method'
:
'removed_by_admin'
,
'user_id'
:
self
.
user_info
[
'user_id'
]
'user_id'
:
self
.
user_info
[
'user_id'
]
...
@@ -1801,7 +1789,6 @@ class TeamPageTest(TeamsTabBase):
...
@@ -1801,7 +1789,6 @@ class TeamPageTest(TeamsTabBase):
{
{
'event_type'
:
'edx.team.learner_added'
,
'event_type'
:
'edx.team.learner_added'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'add_method'
:
'joined_from_team_view'
'add_method'
:
'joined_from_team_view'
}
}
}
}
...
@@ -1880,7 +1867,6 @@ class TeamPageTest(TeamsTabBase):
...
@@ -1880,7 +1867,6 @@ class TeamPageTest(TeamsTabBase):
{
{
'event_type'
:
'edx.team.learner_removed'
,
'event_type'
:
'edx.team.learner_removed'
,
'event'
:
{
'event'
:
{
'course_id'
:
self
.
course_id
,
'remove_method'
:
'self_removal'
'remove_method'
:
'self_removal'
}
}
}
}
...
...
lms/djangoapps/teams/tests/test_views.py
View file @
222c3ba0
...
@@ -548,7 +548,6 @@ class TestListTeamsAPI(EventTestMixin, TeamAPITestCase):
...
@@ -548,7 +548,6 @@ class TestListTeamsAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.searched'
,
'edx.team.searched'
,
course_id
=
unicode
(
self
.
test_course_2
.
id
),
search_text
=
text_search
,
search_text
=
text_search
,
topic_id
=
None
,
topic_id
=
None
,
number_of_results
=
len
(
expected_team_names
)
number_of_results
=
len
(
expected_team_names
)
...
@@ -707,13 +706,11 @@ class TestCreateTeamAPI(EventTestMixin, TeamAPITestCase):
...
@@ -707,13 +706,11 @@ class TestCreateTeamAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.created'
,
'edx.team.created'
,
team_id
=
self
.
_expected_team_id
(
team
,
'fully-specified-team'
),
team_id
=
self
.
_expected_team_id
(
team
,
'fully-specified-team'
),
course_id
=
unicode
(
self
.
test_course_1
.
id
),
)
)
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.learner_added'
,
'edx.team.learner_added'
,
team_id
=
self
.
_expected_team_id
(
team
,
'fully-specified-team'
),
team_id
=
self
.
_expected_team_id
(
team
,
'fully-specified-team'
),
course_id
=
unicode
(
self
.
test_course_1
.
id
),
user_id
=
self
.
users
[
creator
]
.
id
,
user_id
=
self
.
users
[
creator
]
.
id
,
add_method
=
'added_on_create'
add_method
=
'added_on_create'
)
)
...
@@ -821,12 +818,10 @@ class TestDeleteTeamAPI(EventTestMixin, TeamAPITestCase):
...
@@ -821,12 +818,10 @@ class TestDeleteTeamAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.deleted'
,
'edx.team.deleted'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
test_course_1
.
id
)
)
)
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.learner_removed'
,
'edx.team.learner_removed'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
test_course_1
.
id
),
remove_method
=
'team_deleted'
,
remove_method
=
'team_deleted'
,
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
)
)
...
@@ -840,12 +835,10 @@ class TestDeleteTeamAPI(EventTestMixin, TeamAPITestCase):
...
@@ -840,12 +835,10 @@ class TestDeleteTeamAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.deleted'
,
'edx.team.deleted'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
test_course_1
.
id
)
)
)
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.learner_removed'
,
'edx.team.learner_removed'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
test_course_1
.
id
),
remove_method
=
'team_deleted'
,
remove_method
=
'team_deleted'
,
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
)
)
...
@@ -877,7 +870,6 @@ class TestUpdateTeamAPI(EventTestMixin, TeamAPITestCase):
...
@@ -877,7 +870,6 @@ class TestUpdateTeamAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.changed'
,
'edx.team.changed'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
solar_team
.
course_id
),
truncated
=
[],
truncated
=
[],
field
=
'name'
,
field
=
'name'
,
old
=
prev_name
,
old
=
prev_name
,
...
@@ -919,7 +911,6 @@ class TestUpdateTeamAPI(EventTestMixin, TeamAPITestCase):
...
@@ -919,7 +911,6 @@ class TestUpdateTeamAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.changed'
,
'edx.team.changed'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
solar_team
.
course_id
),
truncated
=
[],
truncated
=
[],
field
=
key
,
field
=
key
,
old
=
prev_value
,
old
=
prev_value
,
...
@@ -1220,7 +1211,6 @@ class TestCreateMembershipAPI(EventTestMixin, TeamAPITestCase):
...
@@ -1220,7 +1211,6 @@ class TestCreateMembershipAPI(EventTestMixin, TeamAPITestCase):
'edx.team.learner_added'
,
'edx.team.learner_added'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
user_id
=
self
.
users
[
'student_enrolled_not_on_team'
]
.
id
,
user_id
=
self
.
users
[
'student_enrolled_not_on_team'
]
.
id
,
course_id
=
unicode
(
self
.
solar_team
.
course_id
),
add_method
=
add_method
add_method
=
add_method
)
)
else
:
else
:
...
@@ -1378,7 +1368,6 @@ class TestDeleteMembershipAPI(EventTestMixin, TeamAPITestCase):
...
@@ -1378,7 +1368,6 @@ class TestDeleteMembershipAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.learner_removed'
,
'edx.team.learner_removed'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
solar_team
.
course_id
),
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
,
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
,
remove_method
=
'removed_by_admin'
remove_method
=
'removed_by_admin'
)
)
...
@@ -1396,7 +1385,6 @@ class TestDeleteMembershipAPI(EventTestMixin, TeamAPITestCase):
...
@@ -1396,7 +1385,6 @@ class TestDeleteMembershipAPI(EventTestMixin, TeamAPITestCase):
self
.
assert_event_emitted
(
self
.
assert_event_emitted
(
'edx.team.learner_removed'
,
'edx.team.learner_removed'
,
team_id
=
self
.
solar_team
.
team_id
,
team_id
=
self
.
solar_team
.
team_id
,
course_id
=
unicode
(
self
.
solar_team
.
course_id
),
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
,
user_id
=
self
.
users
[
'student_enrolled'
]
.
id
,
remove_method
=
'self_removal'
remove_method
=
'self_removal'
)
)
...
...
lms/djangoapps/teams/views.py
View file @
222c3ba0
...
@@ -40,6 +40,7 @@ from opaque_keys.edx.keys import CourseKey
...
@@ -40,6 +40,7 @@ from opaque_keys.edx.keys import CourseKey
from
courseware.courses
import
get_course_with_access
,
has_access
from
courseware.courses
import
get_course_with_access
,
has_access
from
eventtracking
import
tracker
from
eventtracking
import
tracker
from
track
import
contexts
from
student.models
import
CourseEnrollment
,
CourseAccessRole
from
student.models
import
CourseEnrollment
,
CourseAccessRole
from
student.roles
import
CourseStaffRole
from
student.roles
import
CourseStaffRole
from
django_comment_client.utils
import
has_discussion_privileges
from
django_comment_client.utils
import
has_discussion_privileges
...
@@ -66,6 +67,16 @@ MAXIMUM_SEARCH_SIZE = 100000
...
@@ -66,6 +67,16 @@ MAXIMUM_SEARCH_SIZE = 100000
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
def
emit_team_event
(
event_name
,
course_key
,
event_data
):
"""
Emit team events with the correct course id context.
"""
context
=
contexts
.
course_context_from_course_id
(
course_key
)
with
tracker
.
get_tracker
()
.
context
(
event_name
,
context
):
tracker
.
emit
(
event_name
,
event_data
)
@receiver
(
post_save
,
sender
=
CourseTeam
)
@receiver
(
post_save
,
sender
=
CourseTeam
)
def
team_post_save_callback
(
sender
,
instance
,
**
kwargs
):
# pylint: disable=unused-argument
def
team_post_save_callback
(
sender
,
instance
,
**
kwargs
):
# pylint: disable=unused-argument
""" Emits signal after the team is saved. """
""" Emits signal after the team is saved. """
...
@@ -76,11 +87,11 @@ def team_post_save_callback(sender, instance, **kwargs): # pylint: disable=unus
...
@@ -76,11 +87,11 @@ def team_post_save_callback(sender, instance, **kwargs): # pylint: disable=unus
if
field
not
in
instance
.
FIELD_BLACKLIST
:
if
field
not
in
instance
.
FIELD_BLACKLIST
:
truncated_fields
=
truncate_fields
(
unicode
(
changed_fields
[
field
]),
unicode
(
getattr
(
instance
,
field
)))
truncated_fields
=
truncate_fields
(
unicode
(
changed_fields
[
field
]),
unicode
(
getattr
(
instance
,
field
)))
truncated_fields
[
'team_id'
]
=
instance
.
team_id
truncated_fields
[
'team_id'
]
=
instance
.
team_id
truncated_fields
[
'course_id'
]
=
unicode
(
instance
.
course_id
)
truncated_fields
[
'field'
]
=
field
truncated_fields
[
'field'
]
=
field
tracker
.
emi
t
(
emit_team_even
t
(
'edx.team.changed'
,
'edx.team.changed'
,
instance
.
course_id
,
truncated_fields
truncated_fields
)
)
...
@@ -377,11 +388,10 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
...
@@ -377,11 +388,10 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
self
.
get_page
()
self
.
get_page
()
)
)
serializer
=
self
.
get_pagination_serializer
(
paginated_results
)
serializer
=
self
.
get_pagination_serializer
(
paginated_results
)
tracker
.
emit
(
'edx.team.searched'
,
{
emit_team_event
(
'edx.team.searched'
,
course_key
,
{
"number_of_results"
:
search_results
[
'total'
],
"number_of_results"
:
search_results
[
'total'
],
"search_text"
:
text_search
,
"search_text"
:
text_search
,
"topic_id"
:
topic_id
,
"topic_id"
:
topic_id
,
"course_id"
:
course_id_string
,
})
})
else
:
else
:
queryset
=
CourseTeam
.
objects
.
filter
(
**
result_filter
)
queryset
=
CourseTeam
.
objects
.
filter
(
**
result_filter
)
...
@@ -455,19 +465,18 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
...
@@ -455,19 +465,18 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
else
:
else
:
team
=
serializer
.
save
()
team
=
serializer
.
save
()
tracker
.
emit
(
'edx.team.created'
,
{
emit_team_event
(
'edx.team.created'
,
course_key
,
{
'team_id'
:
team
.
team_id
,
'team_id'
:
team
.
team_id
'course_id'
:
unicode
(
course_id
)
})
})
if
not
team_administrator
:
if
not
team_administrator
:
# Add the creating user to the team.
# Add the creating user to the team.
team
.
add_user
(
request
.
user
)
team
.
add_user
(
request
.
user
)
tracker
.
emi
t
(
emit_team_even
t
(
'edx.team.learner_added'
,
'edx.team.learner_added'
,
course_key
,
{
{
'team_id'
:
team
.
team_id
,
'team_id'
:
team
.
team_id
,
'user_id'
:
request
.
user
.
id
,
'user_id'
:
request
.
user
.
id
,
'course_id'
:
unicode
(
team
.
course_id
),
'add_method'
:
'added_on_create'
'add_method'
:
'added_on_create'
}
}
)
)
...
@@ -618,14 +627,12 @@ class TeamsDetailView(ExpandableFieldViewMixin, RetrievePatchAPIView):
...
@@ -618,14 +627,12 @@ class TeamsDetailView(ExpandableFieldViewMixin, RetrievePatchAPIView):
# Note: also deletes all team memberships associated with this team
# Note: also deletes all team memberships associated with this team
team
.
delete
()
team
.
delete
()
log
.
info
(
'user
%
d deleted team
%
s'
,
request
.
user
.
id
,
team_id
)
log
.
info
(
'user
%
d deleted team
%
s'
,
request
.
user
.
id
,
team_id
)
tracker
.
emit
(
'edx.team.deleted'
,
{
emit_team_event
(
'edx.team.deleted'
,
team
.
course_id
,
{
'team_id'
:
team_id
,
'team_id'
:
team_id
,
'course_id'
:
unicode
(
team
.
course_id
),
})
})
for
member
in
memberships
:
for
member
in
memberships
:
tracker
.
emit
(
'edx.team.learner_removed'
,
{
emit_team_event
(
'edx.team.learner_removed'
,
team
.
course_id
,
{
'team_id'
:
team_id
,
'team_id'
:
team_id
,
'course_id'
:
unicode
(
team
.
course_id
),
'remove_method'
:
'team_deleted'
,
'remove_method'
:
'team_deleted'
,
'user_id'
:
member
.
user_id
'user_id'
:
member
.
user_id
})
})
...
@@ -1064,12 +1071,12 @@ class MembershipListView(ExpandableFieldViewMixin, GenericAPIView):
...
@@ -1064,12 +1071,12 @@ class MembershipListView(ExpandableFieldViewMixin, GenericAPIView):
try
:
try
:
membership
=
team
.
add_user
(
user
)
membership
=
team
.
add_user
(
user
)
tracker
.
emi
t
(
emit_team_even
t
(
'edx.team.learner_added'
,
'edx.team.learner_added'
,
team
.
course_id
,
{
{
'team_id'
:
team
.
team_id
,
'team_id'
:
team
.
team_id
,
'user_id'
:
user
.
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'
'add_method'
:
'joined_from_team_view'
if
user
==
request
.
user
else
'added_by_another_user'
}
}
)
)
...
@@ -1202,11 +1209,11 @@ class MembershipDetailView(ExpandableFieldViewMixin, GenericAPIView):
...
@@ -1202,11 +1209,11 @@ class MembershipDetailView(ExpandableFieldViewMixin, GenericAPIView):
if
'admin'
in
request
.
QUERY_PARAMS
:
if
'admin'
in
request
.
QUERY_PARAMS
:
removal_method
=
'removed_by_admin'
removal_method
=
'removed_by_admin'
membership
.
delete
()
membership
.
delete
()
tracker
.
emi
t
(
emit_team_even
t
(
'edx.team.learner_removed'
,
'edx.team.learner_removed'
,
team
.
course_id
,
{
{
'team_id'
:
team
.
team_id
,
'team_id'
:
team
.
team_id
,
'course_id'
:
unicode
(
team
.
course_id
),
'user_id'
:
membership
.
user
.
id
,
'user_id'
:
membership
.
user
.
id
,
'remove_method'
:
removal_method
'remove_method'
:
removal_method
}
}
...
...
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