{"action":"created","comment":{"url":"https://api.github.com/repos/openfun/richie/pulls/comments/190188452","pull_request_review_id":122511056,"id":190188452,"diff_hunk":"@@ -0,0 +1,124 @@\n+\"\"\"Test utils for the courses application\"\"\"\n+\n+from django.contrib.auth.models import AnonymousUser, Permission\n+from django.core.exceptions import ImproperlyConfigured\n+from django.test.client import RequestFactory\n+\n+from cms.toolbar.items import Menu, ModalItem\n+from cms.middleware.toolbar import ToolbarMiddleware\n+\n+from apps.core.factories import UserFactory\n+\n+\n+class CheckToolbarMixin:\n+    \"\"\"\n+    Mixin that factorize `check_toolbar_item` method used by several applications\n+    CMS toolbar unit tests\n+    \"\"\"\n+\n+    def check_toolbar_item(self, page_extension, menu_item_text):\n+        \"\"\"\n+        Not a test. This method is a helper to test the toolbar for the presence of a menu item\n+        for editing page extensions.\n+        \"\"\"\n+        # Create different users for each possible level of access\n+        # pylint: disable=too-many-locals\n+        superuser = UserFactory(is_staff=True, is_superuser=True)\n+        staff_with_permission = UserFactory(is_staff=True)\n+        user_with_permission = UserFactory()\n+        staff = UserFactory(is_staff=True)\n+        user = UserFactory()\n+        anonymous = AnonymousUser()\n+\n+        # Add global permission to change page for users concerned\n+        can_change_page = Permission.objects.get(codename=\"change_page\")\n+        staff_with_permission.user_permissions.add(can_change_page)\n+        user_with_permission.user_permissions.add(can_change_page)\n+\n+        cases = [\n+            ([superuser, False, False], \"disabled\"),\n+            ([superuser, True, False], \"active\"),\n+            ([superuser, False, True], \"disabled\"),\n+            ([staff_with_permission, False, False], \"disabled\"),\n+            ([staff_with_permission, True, False], \"active\"),\n+            ([staff_with_permission, False, True], \"disabled\"),\n+            ([staff, False, False], \"missing\"),\n+            ([staff, True, False], \"missing\"),\n+            ([staff, False, True], \"missing\"),\n+            ([user_with_permission, False, False], \"absent\"),\n+            ([user_with_permission, True, False], \"absent\"),\n+            ([user_with_permission, False, True], \"absent\"),\n+            ([user, False, False], \"absent\"),\n+            ([user, True, False], \"absent\"),\n+            ([user, False, True], \"absent\"),\n+            ([anonymous, False, False], \"absent\"),\n+            ([anonymous, True, False], \"absent\"),\n+            ([anonymous, False, True], \"absent\"),\n+        ]\n+        admin_url = \"/en/admin/{app_name:s}/{model_name:s}/{id:d}/change/\".format(\n+            app_name=page_extension._meta.app_label,\n+            model_name=page_extension.__class__.__name__.lower(),\n+            id=page_extension.id,\n+        )\n+\n+        page = page_extension.extended_object\n+        for args, state in cases:\n+            toolbar = get_toolbar_for_page(page, *args)\n+\n+            if state in [\"active\", \"disabled\", \"missing\"]:\n+                page_menu_result = toolbar.find_items(Menu, name=\"Page\")[0]\n+                results = page_menu_result.item.find_items(\n+                    ModalItem, name=menu_item_text\n+                )\n+                if state in [\"active\", \"disabled\"]:\n+                    self.assertEqual(len(results), 1)\n+                    item = results[0].item\n+                    self.assertEqual(item.url, admin_url)\n+\n+                    if state == \"active\":\n+                        self.assertFalse(item.disabled)\n+\n+                    elif state == \"disabled\":\n+                        self.assertTrue(item.disabled)\n+\n+                elif state == \"missing\":\n+                    self.assertEqual(results, [])\n+\n+                else:\n+                    raise ImproperlyConfigured()\n+\n+            elif state == \"absent\":\n+                # The whole toolbar should be hidden\n+                self.assertEqual(toolbar.get_left_items(), [])\n+\n+            else:\n+                raise ImproperlyConfigured()\n+\n+\n+def get_toolbar_for_page(page, user, edit, preview):","path":"apps/persons/tests/utils.py","position":98,"original_position":98,"commit_id":"f77b45b3f6050b2b36fc00d1a0ab4e6b4c575591","original_commit_id":"70f827761e2eab2b8f8fb01626e6ea908926b974","user":{"login":"sampaccoud","id":1427165,"avatar_url":"https://avatars3.githubusercontent.com/u/1427165?v=4","gravatar_id":"","url":"https://api.github.com/users/sampaccoud","html_url":"https://github.com/sampaccoud","followers_url":"https://api.github.com/users/sampaccoud/followers","following_url":"https://api.github.com/users/sampaccoud/following{/other_user}","gists_url":"https://api.github.com/users/sampaccoud/gists{/gist_id}","starred_url":"https://api.github.com/users/sampaccoud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sampaccoud/subscriptions","organizations_url":"https://api.github.com/users/sampaccoud/orgs","repos_url":"https://api.github.com/users/sampaccoud/repos","events_url":"https://api.github.com/users/sampaccoud/events{/privacy}","received_events_url":"https://api.github.com/users/sampaccoud/received_events","type":"User","site_admin":false},"body":"no you're mixing up this method and the method above. This one does not need self.\r\nI think this mixin is fine. It can have a normal method (check_toolbar_item) and a staticmethod (get_toolbar_for_page)","created_at":"2018-05-23T09:53:11Z","updated_at":"2018-05-23T09:53:17Z","html_url":"https://github.com/openfun/richie/pull/148#discussion_r190188452","pull_request_url":"https://api.github.com/repos/openfun/richie/pulls/148","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/openfun/richie/pulls/comments/190188452"},"html":{"href":"https://github.com/openfun/richie/pull/148#discussion_r190188452"},"pull_request":{"href":"https://api.github.com/repos/openfun/richie/pulls/148"}},"in_reply_to_id":190149515},"pull_request":{"url":"https://api.github.com/repos/openfun/richie/pulls/148","id":189559694,"html_url":"https://github.com/openfun/richie/pull/148","diff_url":"https://github.com/openfun/richie/pull/148.diff","patch_url":"https://github.com/openfun/richie/pull/148.patch","issue_url":"https://api.github.com/repos/openfun/richie/issues/148","number":148,"state":"open","locked":false,"title":"Persons application","user":{"login":"rmoch","id":89626,"avatar_url":"https://avatars0.githubusercontent.com/u/89626?v=4","gravatar_id":"","url":"https://api.github.com/users/rmoch","html_url":"https://github.com/rmoch","followers_url":"https://api.github.com/users/rmoch/followers","following_url":"https://api.github.com/users/rmoch/following{/other_user}","gists_url":"https://api.github.com/users/rmoch/gists{/gist_id}","starred_url":"https://api.github.com/users/rmoch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rmoch/subscriptions","organizations_url":"https://api.github.com/users/rmoch/orgs","repos_url":"https://api.github.com/users/rmoch/repos","events_url":"https://api.github.com/users/rmoch/events{/privacy}","received_events_url":"https://api.github.com/users/rmoch/received_events","type":"User","site_admin":false},"body":"## Purpose\r\nAdd Person model to Richie to represent course teachers and news article authors\r\n\r\n- [x] Factorize code common to organization and persons applications\r\n- [x] Add cms template to display child pages \r\n","created_at":"2018-05-22T06:31:51Z","updated_at":"2018-05-23T09:53:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3ccd1f94aa4d58b55a3d13340f0faebb13c00518","assignee":{"login":"rmoch","id":89626,"avatar_url":"https://avatars0.githubusercontent.com/u/89626?v=4","gravatar_id":"","url":"https://api.github.com/users/rmoch","html_url":"https://github.com/rmoch","followers_url":"https://api.github.com/users/rmoch/followers","following_url":"https://api.github.com/users/rmoch/following{/other_user}","gists_url":"https://api.github.com/users/rmoch/gists{/gist_id}","starred_url":"https://api.github.com/users/rmoch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rmoch/subscriptions","organizations_url":"https://api.github.com/users/rmoch/orgs","repos_url":"https://api.github.com/users/rmoch/repos","events_url":"https://api.github.com/users/rmoch/events{/privacy}","received_events_url":"https://api.github.com/users/rmoch/received_events","type":"User","site_admin":false},"assignees":[{"login":"rmoch","id":89626,"avatar_url":"https://avatars0.githubusercontent.com/u/89626?v=4","gravatar_id":"","url":"https://api.github.com/users/rmoch","html_url":"https://github.com/rmoch","followers_url":"https://api.github.com/users/rmoch/followers","following_url":"https://api.github.com/users/rmoch/following{/other_user}","gists_url":"https://api.github.com/users/rmoch/gists{/gist_id}","starred_url":"https://api.github.com/users/rmoch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rmoch/subscriptions","organizations_url":"https://api.github.com/users/rmoch/orgs","repos_url":"https://api.github.com/users/rmoch/repos","events_url":"https://api.github.com/users/rmoch/events{/privacy}","received_events_url":"https://api.github.com/users/rmoch/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":915983269,"url":"https://api.github.com/repos/openfun/richie/labels/needs%20review","name":"needs review","color":"fbca04","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/openfun/richie/pulls/148/commits","review_comments_url":"https://api.github.com/repos/openfun/richie/pulls/148/comments","review_comment_url":"https://api.github.com/repos/openfun/richie/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openfun/richie/issues/148/comments","statuses_url":"https://api.github.com/repos/openfun/richie/statuses/f77b45b3f6050b2b36fc00d1a0ab4e6b4c575591","head":{"label":"openfun:persons","ref":"persons","sha":"f77b45b3f6050b2b36fc00d1a0ab4e6b4c575591","user":{"login":"openfun","id":7224891,"avatar_url":"https://avatars2.githubusercontent.com/u/7224891?v=4","gravatar_id":"","url":"https://api.github.com/users/openfun","html_url":"https://github.com/openfun","followers_url":"https://api.github.com/users/openfun/followers","following_url":"https://api.github.com/users/openfun/following{/other_user}","gists_url":"https://api.github.com/users/openfun/gists{/gist_id}","starred_url":"https://api.github.com/users/openfun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openfun/subscriptions","organizations_url":"https://api.github.com/users/openfun/orgs","repos_url":"https://api.github.com/users/openfun/repos","events_url":"https://api.github.com/users/openfun/events{/privacy}","received_events_url":"https://api.github.com/users/openfun/received_events","type":"Organization","site_admin":false},"repo":{"id":111388461,"name":"richie","full_name":"openfun/richie","owner":{"login":"openfun","id":7224891,"avatar_url":"https://avatars2.githubusercontent.com/u/7224891?v=4","gravatar_id":"","url":"https://api.github.com/users/openfun","html_url":"https://github.com/openfun","followers_url":"https://api.github.com/users/openfun/followers","following_url":"https://api.github.com/users/openfun/following{/other_user}","gists_url":"https://api.github.com/users/openfun/gists{/gist_id}","starred_url":"https://api.github.com/users/openfun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openfun/subscriptions","organizations_url":"https://api.github.com/users/openfun/orgs","repos_url":"https://api.github.com/users/openfun/repos","events_url":"https://api.github.com/users/openfun/events{/privacy}","received_events_url":"https://api.github.com/users/openfun/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openfun/richie","description":"🐬 A FUN CMS for Open edX","fork":false,"url":"https://api.github.com/repos/openfun/richie","forks_url":"https://api.github.com/repos/openfun/richie/forks","keys_url":"https://api.github.com/repos/openfun/richie/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openfun/richie/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openfun/richie/teams","hooks_url":"https://api.github.com/repos/openfun/richie/hooks","issue_events_url":"https://api.github.com/repos/openfun/richie/issues/events{/number}","events_url":"https://api.github.com/repos/openfun/richie/events","assignees_url":"https://api.github.com/repos/openfun/richie/assignees{/user}","branches_url":"https://api.github.com/repos/openfun/richie/branches{/branch}","tags_url":"https://api.github.com/repos/openfun/richie/tags","blobs_url":"https://api.github.com/repos/openfun/richie/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openfun/richie/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openfun/richie/git/refs{/sha}","trees_url":"https://api.github.com/repos/openfun/richie/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openfun/richie/statuses/{sha}","languages_url":"https://api.github.com/repos/openfun/richie/languages","stargazers_url":"https://api.github.com/repos/openfun/richie/stargazers","contributors_url":"https://api.github.com/repos/openfun/richie/contributors","subscribers_url":"https://api.github.com/repos/openfun/richie/subscribers","subscription_url":"https://api.github.com/repos/openfun/richie/subscription","commits_url":"https://api.github.com/repos/openfun/richie/commits{/sha}","git_commits_url":"https://api.github.com/repos/openfun/richie/git/commits{/sha}","comments_url":"https://api.github.com/repos/openfun/richie/comments{/number}","issue_comment_url":"https://api.github.com/repos/openfun/richie/issues/comments{/number}","contents_url":"https://api.github.com/repos/openfun/richie/contents/{+path}","compare_url":"https://api.github.com/repos/openfun/richie/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openfun/richie/merges","archive_url":"https://api.github.com/repos/openfun/richie/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openfun/richie/downloads","issues_url":"https://api.github.com/repos/openfun/richie/issues{/number}","pulls_url":"https://api.github.com/repos/openfun/richie/pulls{/number}","milestones_url":"https://api.github.com/repos/openfun/richie/milestones{/number}","notifications_url":"https://api.github.com/repos/openfun/richie/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openfun/richie/labels{/name}","releases_url":"https://api.github.com/repos/openfun/richie/releases{/id}","deployments_url":"https://api.github.com/repos/openfun/richie/deployments","created_at":"2017-11-20T09:23:40Z","updated_at":"2018-05-22T07:54:01Z","pushed_at":"2018-05-23T09:04:03Z","git_url":"git://github.com/openfun/richie.git","ssh_url":"git@github.com:openfun/richie.git","clone_url":"https://github.com/openfun/richie.git","svn_url":"https://github.com/openfun/richie","homepage":"","size":1820,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":14,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":0,"open_issues":14,"watchers":6,"default_branch":"master"}},"base":{"label":"openfun:master","ref":"master","sha":"095f205acd01cba7a7cc867eb075e253aa002c4f","user":{"login":"openfun","id":7224891,"avatar_url":"https://avatars2.githubusercontent.com/u/7224891?v=4","gravatar_id":"","url":"https://api.github.com/users/openfun","html_url":"https://github.com/openfun","followers_url":"https://api.github.com/users/openfun/followers","following_url":"https://api.github.com/users/openfun/following{/other_user}","gists_url":"https://api.github.com/users/openfun/gists{/gist_id}","starred_url":"https://api.github.com/users/openfun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openfun/subscriptions","organizations_url":"https://api.github.com/users/openfun/orgs","repos_url":"https://api.github.com/users/openfun/repos","events_url":"https://api.github.com/users/openfun/events{/privacy}","received_events_url":"https://api.github.com/users/openfun/received_events","type":"Organization","site_admin":false},"repo":{"id":111388461,"name":"richie","full_name":"openfun/richie","owner":{"login":"openfun","id":7224891,"avatar_url":"https://avatars2.githubusercontent.com/u/7224891?v=4","gravatar_id":"","url":"https://api.github.com/users/openfun","html_url":"https://github.com/openfun","followers_url":"https://api.github.com/users/openfun/followers","following_url":"https://api.github.com/users/openfun/following{/other_user}","gists_url":"https://api.github.com/users/openfun/gists{/gist_id}","starred_url":"https://api.github.com/users/openfun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openfun/subscriptions","organizations_url":"https://api.github.com/users/openfun/orgs","repos_url":"https://api.github.com/users/openfun/repos","events_url":"https://api.github.com/users/openfun/events{/privacy}","received_events_url":"https://api.github.com/users/openfun/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openfun/richie","description":"🐬 A FUN CMS for Open edX","fork":false,"url":"https://api.github.com/repos/openfun/richie","forks_url":"https://api.github.com/repos/openfun/richie/forks","keys_url":"https://api.github.com/repos/openfun/richie/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openfun/richie/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openfun/richie/teams","hooks_url":"https://api.github.com/repos/openfun/richie/hooks","issue_events_url":"https://api.github.com/repos/openfun/richie/issues/events{/number}","events_url":"https://api.github.com/repos/openfun/richie/events","assignees_url":"https://api.github.com/repos/openfun/richie/assignees{/user}","branches_url":"https://api.github.com/repos/openfun/richie/branches{/branch}","tags_url":"https://api.github.com/repos/openfun/richie/tags","blobs_url":"https://api.github.com/repos/openfun/richie/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openfun/richie/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openfun/richie/git/refs{/sha}","trees_url":"https://api.github.com/repos/openfun/richie/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openfun/richie/statuses/{sha}","languages_url":"https://api.github.com/repos/openfun/richie/languages","stargazers_url":"https://api.github.com/repos/openfun/richie/stargazers","contributors_url":"https://api.github.com/repos/openfun/richie/contributors","subscribers_url":"https://api.github.com/repos/openfun/richie/subscribers","subscription_url":"https://api.github.com/repos/openfun/richie/subscription","commits_url":"https://api.github.com/repos/openfun/richie/commits{/sha}","git_commits_url":"https://api.github.com/repos/openfun/richie/git/commits{/sha}","comments_url":"https://api.github.com/repos/openfun/richie/comments{/number}","issue_comment_url":"https://api.github.com/repos/openfun/richie/issues/comments{/number}","contents_url":"https://api.github.com/repos/openfun/richie/contents/{+path}","compare_url":"https://api.github.com/repos/openfun/richie/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openfun/richie/merges","archive_url":"https://api.github.com/repos/openfun/richie/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openfun/richie/downloads","issues_url":"https://api.github.com/repos/openfun/richie/issues{/number}","pulls_url":"https://api.github.com/repos/openfun/richie/pulls{/number}","milestones_url":"https://api.github.com/repos/openfun/richie/milestones{/number}","notifications_url":"https://api.github.com/repos/openfun/richie/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openfun/richie/labels{/name}","releases_url":"https://api.github.com/repos/openfun/richie/releases{/id}","deployments_url":"https://api.github.com/repos/openfun/richie/deployments","created_at":"2017-11-20T09:23:40Z","updated_at":"2018-05-22T07:54:01Z","pushed_at":"2018-05-23T09:04:03Z","git_url":"git://github.com/openfun/richie.git","ssh_url":"git@github.com:openfun/richie.git","clone_url":"https://github.com/openfun/richie.git","svn_url":"https://github.com/openfun/richie","homepage":"","size":1820,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":14,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":0,"open_issues":14,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openfun/richie/pulls/148"},"html":{"href":"https://github.com/openfun/richie/pull/148"},"issue":{"href":"https://api.github.com/repos/openfun/richie/issues/148"},"comments":{"href":"https://api.github.com/repos/openfun/richie/issues/148/comments"},"review_comments":{"href":"https://api.github.com/repos/openfun/richie/pulls/148/comments"},"review_comment":{"href":"https://api.github.com/repos/openfun/richie/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openfun/richie/pulls/148/commits"},"statuses":{"href":"https://api.github.com/repos/openfun/richie/statuses/f77b45b3f6050b2b36fc00d1a0ab4e6b4c575591"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"sampaccoud"}}