Jump to >

File Diff Resource

Provides information on per-file diffs.

Each of these contains a single, self-contained diff file that applies to exactly one file on a repository.

Details

Name file
URI /api/review-requests/{review_request_id}/diffs/{diff_revision}/files/{filediff_id}/
Token Policy ID file_diff
HTTP Methods
  • GET -

    Returns the information or contents on a per-file diff.

  • PUT -

    Updates a per-file diff.

Parent Resource

File Diff List Resource

Child Resources
Anonymous Access

Yes, if anonymous site access is enabled

Fields

binaryBoolean

Whether this represents a binary file.

Added in 4.0.6

dest_attachmentDiff File Attachment Resource

The file attachment for the contents of the patched file for this file diff, if representing a binary file.

Added in 2.0

dest_detailString

Additional information of the destination file. This is parsed from the diff, but is usually not used for anything.

dest_fileString

The new name of the patched file. This may be the same as the existing file.

extra_dataDictionary

Extra data as part of the diff. This can be set by the API or extensions.

Added in 2.0

idInteger

The numeric ID of the file diff.

source_attachmentDiff File Attachment Resource

The file attachment for the contents of the original file for this file diff, if representing a binary file.

Added in 2.0

source_fileString

The original name of the modified file in the diff.

source_revisionString

The revision of the file being modified. This is a valid revision in the repository.

statusString

The status of the file. This is one of copied, deleted, modified, moved, or unknown.

Added in 2.5.11

HTTP GET

Returns the information or contents on a per-file diff.

The output varies by mimetype.

If application/json or application/xml is used, then the fields for the diff are returned, like with any other resource.

If text/x-patch is used, then the actual diff file itself is returned. This diff should be as it was when uploaded originally, for this file only, with potentially some extra SCM-specific headers stripped.

If application/vnd.reviewboard.org.diff.data+json or application/vnd.reviewboard.org.diff.data+xml is used, then the raw diff data (lists of inserts, deletes, replaces, moves, header information, etc.) is returned in either JSON or XML. This contains nearly all of the information used to render the diff in the diff viewer, and can be useful for building a diff viewer that interfaces with Review Board.

If ?syntax-highlighting=1 is passed, the rendered diff content for each line will contain HTML markup showing syntax highlighting. Otherwise, the content will be in plain text.

The format of the diff data is a bit complex. The data is stored under a top-level diff_data element and contains the following information:

binaryBoolean

Whether or not the file is a binary file. Binary files won’t have any diff content to display.

changed_chunk_indexesList of Integer

The list of chunks in the diff that have actual changes (inserts, deletes, or replaces).

chunksList of Dictionary

A list of chunks. These are used to render the diff. See below.

new_fileBoolean

Whether or not this is a newly added file, rather than an existing file in the repository.

num_changesInteger

The number of changes made in this file (chunks of adds, removes, or deletes).

Each chunk contains the following fields:

changeOne of equal, delete, insert, replace

The type of change on this chunk. The type influences what sort of information is available for the chunk.

collapsableBoolean

Whether or not this chunk is collapseable. A collapseable chunk is one that is hidden by default in the diff viewer, but can be expanded. These will always be equal chunks, but not every equal chunk is necessarily collapseable (as they may be there to provide surrounding context for the changes).

indexInteger

The index of the chunk. This is 0-based.

linesList of List

The list of rendered lines for a side-by-side diff. Each entry in the list is itself a list with 8 items:

  1. Row number of the line in the combined side-by-side diff.

  2. The line number of the line in the left-hand file, as an integer (for replace, delete, and equal chunks) or an empty string (for insert).

  3. The text for the line in the left-hand file.

  4. The indexes within the text for the left-hand file that have been replaced by text in the right-hand side. Each index is a list of start, end positions, 0-based. This is only available for replace lines. Otherwise the list is empty.

  5. The line number of the line in the right-hand file, as an integer (for replace, insert and equal chunks) or an empty string (for delete).

  6. The text for the line in the right-hand file.

  7. The indexes within the text for the right-hand file that are replacements for text in the left-hand file. Each index is a list of start, end positions, 0-based. This is only available for replace lines. Otherwise the list is empty.

  8. A boolean that indicates if the line contains only whitespace changes.

metaDictionary

Additional information about the chunk. See below for more information.

numlinesInteger

The number of lines in the chunk.

A chunk’s meta information contains:

headersList of [String, String]

Class definitions, function definitions, or other useful headers that should be displayed before this chunk. This helps users to identify where in a file they are and what the current chunk may be a part of.

whitespace_chunkBoolean

Whether or not the entire chunk consists only of whitespace changes.

whitespace_linesList of [Integer, Integer]

A list of (start, end) row indexes in the lins that contain whitespace-only changes. These are 1-based.

Other meta information may be available, but most is intended for internal use and shouldn’t be relied upon.

Errors

100 - Does Not ExistHTTP 404 - Not Found Object does not exist
101 - Permission DeniedHTTP 403 - Forbidden You don’t have permission for this
103 - Not Logged InHTTP 401 - Unauthorized You are not logged in
112 - OAuth2 Missing Scope ErrorHTTP 403 - Forbidden Your OAuth2 token lacks the necessary scopes for this request.
113 - OAuth2 Access Denied ErrorHTTP 403 - Forbidden OAuth2 token access for this resource is prohibited.

HTTP PUT

Updates a per-file diff.

This is used solely for updating extra data on a file’s diff. The contents of a diff cannot be modified.

Extra data can be stored later lookup. See Storing/Accessing Extra Data for more information.

Errors

100 - Does Not ExistHTTP 404 - Not Found Object does not exist
101 - Permission DeniedHTTP 403 - Forbidden You don’t have permission for this
103 - Not Logged InHTTP 401 - Unauthorized You are not logged in
105 - Invalid Form DataHTTP 400 - Bad Request One or more fields had errors
112 - OAuth2 Missing Scope ErrorHTTP 403 - Forbidden Your OAuth2 token lacks the necessary scopes for this request.
113 - OAuth2 Access Denied ErrorHTTP 403 - Forbidden OAuth2 token access for this resource is prohibited.

Examples

text/x-patch

$ curl http://reviews.example.com/api10/1/44/ -H "Accept: text/x-patch"
Content-Type: text/x-patch
Content-Disposition: inline; filename=tests.py.patch
Last-Modified: Fri, 10 Aug 2018 22:16:22 GMT
ETag: 3b3461101547c83f9392f712359af6e7616af6da
Vary: Accept, Cookie
diff --git a/tests.py b/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..0dd5ce553d79b5b09b2d979cda92f321e1757e26
--- /dev/null
+++ b/tests.py
@@ -0,0 +1,4058 @@
+import os
+
+from django.conf import settings
+from django.contrib.auth.models import User, Permission
+from django.core import mail
+from django.test import TestCase
+from django.utils import simplejson
+from djblets.siteconfig.models import SiteConfiguration
+from djblets.webapi.errors import DOES_NOT_EXIST, INVALID_ATTRIBUTE, \
+                                  INVALID_FORM_DATA, PERMISSION_DENIED
+
+from reviewboard import initialize
+from reviewboard.diffviewer.models import DiffSet
+from reviewboard.notifications.tests import EmailTestHelper
+from reviewboard.reviews.models import Group, ReviewRequest, \
+                                       ReviewRequestDraft, Review, \
+                                       Comment, Screenshot, ScreenshotComment
+from reviewboard.scmtools.models import Repository, Tool
+from reviewboard.site.urlresolvers import local_site_reverse
+from reviewboard.site.models import LocalSite
+from reviewboard.webapi.errors import INVALID_REPOSITORY
+
+
+class BaseWebAPITestCase(TestCase, EmailTestHelper):
+    fixtures = ['test_users', 'test_reviewrequests', 'test_scmtools',
+                'test_site']
+    local_site_name = 'local-site-1'
+
+    def setUp(self):
+        initialize()
+
+        siteconfig = SiteConfiguration.objects.get_current()
+        siteconfig.set("mail_send_review_mail", True)
+        siteconfig.set("auth_require_sitewide_login", False)
+        siteconfig.save()
+        mail.outbox = []
+
+        svn_repo_path = os.path.join(os.path.dirname(__file__),
+                                     '../scmtools/testdata/svn_repo')
+        self.repository = Repository(name='Subversion SVN',
+                                     path='file://' + svn_repo_path,
+                                     tool=Tool.objects.get(name='Subversion'))
+        self.repository.save()
+
+        self.client.login(username="grumpy", password="grumpy")
+        self.user = User.objects.get(username="grumpy")
+
+        self.base_url = 'http://testserver'
+
+    def tearDown(self):
+        self.client.logout()
+
+    def api_func_wrapper(self, api_func, path, query, expected_status,
+                         follow_redirects, expected_redirects):
+        response = api_func(path, query, follow=follow_redirects)
+        self.assertEqual(response.status_code, expected_status)
+
+        if expected_redirects:
+            self.assertEqual(len(response.redirect_chain),
+                             len(expected_redirects))
+
+            for redirect in expected_redirects:
+                self.assertEqual(response.redirect_chain[0][0],
+                                 self.base_url + expected_redirects[0])
+
+        return response
+
+    def apiGet(self, path, query={}, follow_redirects=False,
+               expected_status=200, expected_redirects=[]):
+        path = self._normalize_path(path)
+
+        print 'GETing %s' % path
+        print "Query data: %s" % query
+
+        response = self.api_func_wrapper(self.client.get, path, query,
+                                         expected_status, follow_redirects,
+                                         expected_redirects)
+
+        print "Raw response: %s" % response.content
+
+        rsp = simplejson.loads(response.content)
+        print "Response: %s" % rsp
+
+        return rsp
+
+    def api_post_with_response(self, path, query={}, expected_status=201):
+        path = self._normalize_path(path)
+
+        print 'POSTing to %s' % path
+        print "Post data: %s" % query
+        response = self.client.post(path, query)
+        print "Raw response: %s" % response.content
+        self.assertEqual(response.status_code, expected_status)
+
+        return self._get_result(response, expected_status), response
+
+    def apiPost(self, *args, **kwargs):
+        rsp, result = self.api_post_with_response(*args, **kwargs)
+
+        return rsp
+
+    def apiPut(self, path, query={}, expected_status=200,
+               follow_redirects=False, expected_redirects=[]):
+        path = self._normalize_path(path)
+
+        print 'PUTing to %s' % path
+        print "Post data: %s" % query
+        response = self.api_func_wrapper(self.client.put, path, query,
+                                         expected_status, follow_redirects,
+                                         expected_redirects)
+        print "Raw response: %s" % response.content
+        self.assertEqual(response.status_code, expected_status)
+
+        return self._get_result(response, expected_status)
+
+    def apiDelete(self, path, expected_status=204):
+        path = self._normalize_path(path)
+
+        print 'DELETEing %s' % path
+        response = self.client.delete(path)
+        print "Raw response: %s" % response.content
+        self.assertEqual(response.status_code, expected_status)
+
+        return self._get_result(response, expected_status)
+
+    def _normalize_path(self, path):
+        if path.startswith(self.base_url):
+            return path[len(self.base_url):]
+        else:
+            return path
+
+    def _get_result(self, response, expected_status):
+        if expected_status == 204:
+            self.assertEqual(response.content, '')
+            rsp = None
+        else:
+            rsp = simplejson.loads(response.content)
+            print "Response: %s" % rsp
+
+        return rsp
+
+    #
+    # Some utility functions shared across test suites.
+    #
+    def _postNewReviewRequest(self, local_site_name=None,
+                              repository=None):
+        """Creates a review request and returns the payload response."""
+        if not repository:
+            repository = self.repository
+        rsp = self.apiPost(
+            ReviewRequestResourceTests.get_list_url(local_site_name),
+            { 'repository': repository.path, })
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(
+            rsp['review_request']['links']['repository']['href'],
+            self.base_url +
+            RepositoryResourceTests.get_item_url(repository.id,
+                                                 local_site_name))
+
+        return rsp
+
+    def _postNewReview(self, review_request, body_top="",
+                       body_bottom=""):
+        """Creates a review and returns the payload response."""
+        if review_request.local_site:
+            local_site_name = review_request.local_site.name
+        else:
+            local_site_name = None
+
+        post_data = {
+            'body_top': body_top,
+            'body_bottom': body_bottom,
+        }
+
+        rsp = self.apiPost(ReviewResourceTests.get_list_url(review_request,
+                                                            local_site_name),
+                           post_data)
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['review']['body_top'], body_top)
+        self.assertEqual(rsp['review']['body_bottom'], body_bottom)
+
+        return rsp
+
+    def _postNewDiffComment(self, review_request, review_id, comment_text,
+                            filediff_id=None, interfilediff_id=None,
+                            first_line=10, num_lines=5):
+        """Creates a diff comment and returns the payload response."""
+        if filediff_id is None:
+            diffset = review_request.diffset_history.diffsets.latest()
+            filediff = diffset.files.all()[0]
+            filediff_id = filediff.id
+
+        data = {
+            'filediff_id': filediff_id,
+            'text': comment_text,
+            'first_line': first_line,
+            'num_lines': num_lines,
+        }
+
+        if interfilediff_id is not None:
+            data['interfilediff_id'] = interfilediff_id
+
+        if review_request.local_site:
+            local_site_name = review_request.local_site.name
+        else:
+            local_site_name = None
+
+        review = Review.objects.get(pk=review_id)
+
+        rsp = self.apiPost(
+            ReviewCommentResourceTests.get_list_url(review, local_site_name),
+            data)
+        self.assertEqual(rsp['stat'], 'ok')
+
+        return rsp
+
+    def _postNewScreenshotComment(self, review_request, review_id, screenshot,
+                                  comment_text, x, y, w, h):
+        """Creates a screenshot comment and returns the payload response."""
+        if review_request.local_site:
+            local_site_name = review_request.local_site.name
+        else:
+            local_site_name = None
+
+        post_data = {
+            'screenshot_id': screenshot.id,
+            'text': comment_text,
+            'x': x,
+            'y': y,
+            'w': w,
+            'h': h,
+        }
+
+        review = Review.objects.get(pk=review_id)
+        rsp = self.apiPost(
+            DraftReviewScreenshotCommentResourceTests.get_list_url(
+                review, local_site_name),
+            post_data)
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        return rsp
+
+    def _postNewScreenshot(self, review_request):
+        """Creates a screenshot and returns the payload response."""
+        if review_request.local_site:
+            local_site_name = review_request.local_site.name
+        else:
+            local_site_name = None
+
+        f = open(self._getTrophyFilename(), "r")
+        self.assert_(f)
+
+        post_data = {
+            'path': f,
+        }
+
+        rsp = self.apiPost(
+            ScreenshotResourceTests.get_list_url(review_request,
+                                                 local_site_name),
+            post_data)
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        return rsp
+
+    def _postNewDiff(self, review_request):
+        """Creates a diff and returns the payload response."""
+        diff_filename = os.path.join(
+            os.path.dirname(os.path.dirname(__file__)),
+            "scmtools", "testdata", "svn_makefile.diff")
+
+        f = open(diff_filename, "r")
+        rsp = self.apiPost(DiffResourceTests.get_list_url(review_request), {
+            'path': f,
+            'basedir': "/trunk",
+        })
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        return rsp
+
+    def _getTrophyFilename(self):
+        return os.path.join(settings.HTDOCS_ROOT,
+                            "media", "rb", "images", "trophy.png")
+
+
+class ServerInfoResourceTests(BaseWebAPITestCase):
+    """Testing the ServerInfoResource APIs."""
+    def test_get_server_info(self):
+        """Testing the GET info/ API"""
+        rsp = self.apiGet(self.get_url())
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('info' in rsp)
+        self.assertTrue('product' in rsp['info'])
+        self.assertTrue('site' in rsp['info'])
+
+    def test_get_server_info_with_site(self):
+        """Testing the GET info/ API with a local site"""
+        self.client.logout()
+        self.client.login(username="doc", password="doc")
+
+        rsp = self.apiGet(self.get_url(self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('info' in rsp)
+        self.assertTrue('product' in rsp['info'])
+        self.assertTrue('site' in rsp['info'])
+
+    def test_get_server_info_with_site_no_access(self):
+        """Testing the GET info/ API with a local site and Permission Denied error"""
+        self.apiGet(self.get_url(self.local_site_name),
+                    expected_status=403)
+
+    def get_url(self, local_site_name=None):
+        return local_site_reverse('info-resource',
+                                  local_site_name=local_site_name)
+
+
+class SessionResourceTests(BaseWebAPITestCase):
+    """Testing the SessionResource APIs."""
+    def test_get_session_with_logged_in_user(self):
+        """Testing the GET session/ API with logged in user"""
+        rsp = self.apiGet(self.get_url())
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('session' in rsp)
+        self.assertTrue(rsp['session']['authenticated'])
+        self.assertEqual(rsp['session']['links']['user']['title'],
+                         self.user.username)
+
+    def test_get_session_with_anonymous_user(self):
+        """Testing the GET session/ API with anonymous user"""
+        self.client.logout()
+
+        rsp = self.apiGet(self.get_url())
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('session' in rsp)
+        self.assertFalse(rsp['session']['authenticated'])
+
+    def test_get_session_with_site(self):
+        """Testing the GET session/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiGet(self.get_url(self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('session' in rsp)
+        self.assertTrue(rsp['session']['authenticated'])
+        self.assertEqual(rsp['session']['links']['user']['title'], 'doc')
+
+    def test_get_session_with_site_no_access(self):
+        """Testing the GET session/ API with a local site and Permission Denied error"""
+        self.apiGet(self.get_url(self.local_site_name),
+                    expected_status=403)
+
+    def get_url(self, local_site_name=None):
+        return local_site_reverse('session-resource',
+                                  local_site_name=local_site_name)
+
+
+class RepositoryResourceTests(BaseWebAPITestCase):
+    """Testing the RepositoryResource APIs."""
+
+    def test_get_repositories(self):
+        """Testing the GET repositories/ API"""
+        rsp = self.apiGet(self.get_list_url())
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['repositories']),
+                         Repository.objects.accessible(self.user).count())
+
+    def test_get_repositories_with_site(self):
+        """Testing the GET repositories/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiGet(self.get_list_url(self.local_site_name))
+        self.assertEqual(len(rsp['repositories']),
+                         Repository.objects.filter(
+                             local_site__name=self.local_site_name).count())
+
+    def test_get_repositories_with_site_no_access(self):
+        """Testing the GET repositories/ API with a local site and Permission Denied error"""
+        self.apiGet(self.get_list_url(self.local_site_name),
+                    expected_status=403)
+
+    def get_list_url(self, local_site_name=None):
+        return local_site_reverse('repositories-resource',
+                                  local_site_name=local_site_name)
+
+    @classmethod
+    def get_item_url(cls, repository_id, local_site_name=None):
+        return local_site_reverse('repository-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'repository_id': repository_id,
+                                  })
+
+
+class RepositoryInfoResourceTests(BaseWebAPITestCase):
+    """Testing the RepositoryInfoResource APIs."""
+    def test_get_repository_info(self):
+        """Testing the GET repositories/<id>/info API"""
+        rsp = self.apiGet(self.get_url(self.repository))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['info'],
+                         self.repository.get_scmtool().get_repository_info())
+
+    def test_get_repository_info_with_site(self):
+        """Testing the GET repositories/<id>/info API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        repository = Repository.objects.get(name='V8 SVN')
+        rsp = self.apiGet(self.get_url(repository, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['info'],
+                         repository.get_scmtool().get_repository_info())
+
+    def test_get_repository_info_with_site_no_access(self):
+        """Testing the GET repositories/<id>/info API with a local site and Permission Denied error"""
+        repository = Repository.objects.get(name='V8 SVN')
+
+        self.apiGet(self.get_url(self.repository, self.local_site_name),
+                    expected_status=403)
+
+    def get_url(self, repository, local_site_name=None):
+        return local_site_reverse('info-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'repository_id': repository.pk,
+                                  })
+
+
+class ReviewGroupResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewGroupResource APIs."""
+
+    def test_get_groups(self):
+        """Testing the GET groups/ API"""
+        rsp = self.apiGet(self.get_list_url())
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['groups']),
+                         Group.objects.accessible(self.user).count())
+        self.assertEqual(len(rsp['groups']), 4)
+
+    def test_get_groups_with_site(self):
+        """Testing the GET groups/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        groups = Group.objects.accessible(self.user, local_site=local_site)
+
+        rsp = self.apiGet(self.get_list_url(self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['groups']), groups.count())
+        self.assertEqual(len(rsp['groups']), 1)
+
+    def test_get_groups_with_site_no_access(self):
+        """Testing the GET groups/ API with a local site and Permission Denied error"""
+        self.apiGet(self.get_list_url(self.local_site_name),
+                    expected_status=403)
+
+    def test_get_groups_with_q(self):
+        """Testing the GET groups/?q= API"""
+        rsp = self.apiGet(self.get_list_url(), {'q': 'dev'})
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['groups']), 1) #devgroup
+
+    def test_get_group_public(self):
+        """Testing the GET groups/<id>/ API"""
+        group = Group.objects.create(name='test-group')
+
+        rsp = self.apiGet(self.get_item_url(group.name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['group']['name'], group.name)
+        self.assertEqual(rsp['group']['display_name'], group.display_name)
+        self.assertEqual(rsp['group']['invite_only'], False)
+
+    def test_get_group_invite_only(self):
+        """Testing the GET groups/<id>/ API with invite-only"""
+        group = Group.objects.create(name='test-group', invite_only=True)
+        group.users.add(self.user)
+
+        rsp = self.apiGet(self.get_item_url(group.name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['group']['invite_only'], True)
+
+    def test_get_group_invite_only_with_permission_denied_error(self):
+        """Testing the GET groups/<id>/ API with invite-only and Permission Denied error"""
+        group = Group.objects.create(name='test-group', invite_only=True)
+
+        rsp = self.apiGet(self.get_item_url(group.name),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_group_with_site(self):
+        """Testing the GET groups/<id>/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        group = Group.objects.get(name='sitegroup')
+
+        rsp = self.apiGet(self.get_item_url('sitegroup', self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['group']['name'], group.name)
+        self.assertEqual(rsp['group']['display_name'], group.display_name)
+
+    def test_get_group_with_site_no_access(self):
+        """Testing the GET groups/<id>/ API with a local site and Permission Denied error"""
+        self.apiGet(self.get_item_url('sitegroup', self.local_site_name),
+                    expected_status=403)
+
+    def get_list_url(self, local_site_name=None):
+        return local_site_reverse('groups-resource',
+                                  local_site_name=local_site_name)
+
+    def get_item_url(self, group_name, local_site_name=None):
+        return local_site_reverse('group-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'group_name': group_name,
+                                  })
+
+
+class UserResourceTests(BaseWebAPITestCase):
+    """Testing the UserResource API tests."""
+
+    def test_get_users(self):
+        """Testing the GET users/ API"""
+        rsp = self.apiGet(self.get_list_url())
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['users']), User.objects.count())
+
+    def test_get_users_with_q(self):
+        """Testing the GET users/?q= API"""
+        rsp = self.apiGet(self.get_list_url(), {'q': 'gru'})
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['users']), 1) # grumpy
+
+    def test_get_users_with_site(self):
+        """Testing the GET users/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        rsp = self.apiGet(self.get_list_url(self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['users']), local_site.users.count())
+
+    def test_get_users_with_site_no_access(self):
+        """Testing the GET users/ API with a local site and Permission Denied error"""
+        self.apiGet(self.get_list_url(self.local_site_name),
+                    expected_status=403)
+
+    def test_get_user(self):
+        """Testing the GET users/<username>/ API"""
+        username = 'doc'
+        user = User.objects.get(username=username)
+
+        rsp = self.apiGet(self.get_item_url(username))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['user']['username'], user.username)
+        self.assertEqual(rsp['user']['first_name'], user.first_name)
+        self.assertEqual(rsp['user']['last_name'], user.last_name)
+        self.assertEqual(rsp['user']['id'], user.id)
+        self.assertEqual(rsp['user']['email'], user.email)
+
+    def test_get_user_with_site(self):
+        """Testing the GET users/<username>/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        username = 'doc'
+        user = User.objects.get(username=username)
+
+        rsp = self.apiGet(self.get_item_url(username, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['user']['username'], user.username)
+        self.assertEqual(rsp['user']['first_name'], user.first_name)
+        self.assertEqual(rsp['user']['last_name'], user.last_name)
+        self.assertEqual(rsp['user']['id'], user.id)
+        self.assertEqual(rsp['user']['email'], user.email)
+
+    def test_get_missing_user_with_site(self):
+        """Testing the GET users/<username>/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiGet(self.get_item_url('dopey', self.local_site_name),
+                          expected_status=404)
+
+    def test_get_user_with_site_no_access(self):
+        """Testing the GET users/<username>/ API with a local site and Permission Denied error."""
+        self.apiGet(self.get_item_url('doc', self.local_site_name),
+                    expected_status=403)
+
+    def get_list_url(self, local_site_name=None):
+        return local_site_reverse('users-resource',
+                                  local_site_name=local_site_name)
+
+    @classmethod
+    def get_item_url(cls, username, local_site_name=None):
+        return local_site_reverse('user-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'username': username,
+                                  })
+
+
+class WatchedReviewRequestResourceTests(BaseWebAPITestCase):
+    """Testing the WatchedReviewRequestResource API tests."""
+
+    def test_post_watched_review_request(self):
+        """Testing the POST users/<username>/watched/review_request/ API"""
+        review_request = ReviewRequest.objects.public()[0]
+        rsp = self.apiPost(self.get_list_url(self.user.username), {
+            'object_id': review_request.display_id,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assert_(review_request in
+                     self.user.get_profile().starred_review_requests.all())
+
+    def test_post_watched_review_request_with_does_not_exist_error(self):
+        """Testing the POST users/<username>/watched/review_request/ with Does Not Exist error"""
+        rsp = self.apiPost(self.get_list_url(self.user.username), {
+            'object_id': 999,
+        }, expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_post_watched_review_request_with_site(self):
+        """Testing the POST users/<username>/watched/review_request/ API with a local site"""
+        username = 'doc'
+        user = User.objects.get(username=username)
+
+        self.client.logout()
+        self.client.login(username=username, password='doc')
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+
+        rsp = self.apiPost(self.get_list_url(username, self.local_site_name),
+                           { 'object_id': review_request.display_id, })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue(review_request in
+                        user.get_profile().starred_review_requests.all())
+
+    def test_post_watched_review_request_with_site_does_not_exist_error(self):
+        """Testing the POST users/<username>/watched/review_request/ API with a local site and Does Not Exist error"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiPost(self.get_list_url('doc', self.local_site_name),
+                           { 'object_id': 10, },
+                           expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_post_watched_review_request_with_site_no_access(self):
+        """Testing the POST users/<username>/watched/review_request/ API with a local site and Permission Denied error"""
+        rsp = self.apiPost(self.get_list_url('doc', self.local_site_name),
+                           { 'object_id': 10, },
+                           expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_delete_watched_review_request(self):
+        """Testing the DELETE users/<username>/watched/review_request/ API"""
+        # First, star it.
+        self.test_post_watched_review_request()
+
+        review_request = ReviewRequest.objects.public()[0]
+        self.apiDelete(self.get_item_url(self.user.username,
+                                          review_request.display_id))
+        self.assertTrue(review_request not in
+                        self.user.get_profile().starred_review_requests.all())
+
+    def test_delete_watched_review_request_with_does_not_exist_error(self):
+        """Testing the DELETE users/<username>/watched/review_request/ API with Does Not Exist error"""
+        rsp = self.apiDelete(self.get_item_url(self.user.username, 999),
+                             expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_delete_watched_review_request_with_site(self):
+        """Testing the DELETE users/<username>/watched/review_request/ API with a local site"""
+        self.test_post_watched_review_request_with_site()
+
+        user = User.objects.get(username='doc')
+        review_request = ReviewRequest.objects.get(
+            local_id=1, local_site__name=self.local_site_name)
+
+        self.apiDelete(self.get_item_url(user.username,
+                                          review_request.display_id,
+                                          self.local_site_name))
+        self.assertTrue(review_request not in
+                        user.get_profile().starred_review_requests.all())
+
+    def test_delete_watched_review_request_with_site_no_access(self):
+        """Testing the DELETE users/<username>/watched/review_request/ API with a local site and Permission Denied error"""
+        rsp = self.apiDelete(self.get_item_url(self.user.username, 1,
+                                                self.local_site_name),
+                             expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_watched_review_requests(self):
+        """Testing the GET users/<username>/watched/review_request/ API"""
+        self.test_post_watched_review_request()
+
+        rsp = self.apiGet(self.get_list_url(self.user.username))
+        self.assertEqual(rsp['stat'], 'ok')
+
+        watched = self.user.get_profile().starred_review_requests.all()
+        apiwatched = rsp['watched_review_requests']
+
+        self.assertEqual(len(watched), len(apiwatched))
+        for i in range(len(watched)):
+            self.assertEqual(watched[i].id,
+                             apiwatched[i]['watched_review_request']['id'])
+            self.assertEqual(watched[i].summary,
+                             apiwatched[i]['watched_review_request']['summary'])
+
+    def test_get_watched_review_requests_with_site(self):
+        """Testing the GET users/<username>/watched/review_request/ API with a local site"""
+        username = 'doc'
+        user = User.objects.get(username=username)
+
+        self.test_post_watched_review_request_with_site()
+
+        rsp = self.apiGet(self.get_list_url(username, self.local_site_name))
+
+        watched = user.get_profile().starred_review_requests.filter(
+            local_site__name=self.local_site_name)
+        apiwatched = rsp['watched_review_requests']
+
+        self.assertEqual(len(watched), len(apiwatched))
+        for i in range(len(watched)):
+            self.assertEqual(watched[i].display_id,
+                             apiwatched[i]['watched_review_request']['id'])
+            self.assertEqual(watched[i].summary,
+                             apiwatched[i]['watched_review_request']['summary'])
+
+    def test_get_watched_review_requests_with_site_no_access(self):
+        """Testing the GET users/<username>/watched/review_request/ API with a local site and Permission Denied error"""
+        rsp = self.apiGet(self.get_list_url(self.user.username,
+                                             self.local_site_name),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_watched_review_requests_with_site_does_not_exist(self):
+        """Testing the GET users/<username>/watched/review_request/ API with a local site and Does Not Exist error"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiGet(self.get_list_url(self.user.username,
+                                             self.local_site_name),
+                          expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def get_list_url(self, username, local_site_name=None):
+        return local_site_reverse('watched-review-requests-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'username': username,
+                                  })
+
+    def get_item_url(self, username, object_id, local_site_name=None):
+        return local_site_reverse('watched-review-request-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'username': username,
+                                      'watched_obj_id': object_id,
+                                  })
+
+
+class WatchedReviewGroupResourceTests(BaseWebAPITestCase):
+    """Testing the WatchedReviewGroupResource API tests."""
+
+    def test_post_watched_review_group(self):
+        """Testing the POST users/<username>/watched/review-groups/ API"""
+        group = Group.objects.get(name='devgroup', local_site=None)
+
+        rsp = self.apiPost(self.get_list_url(self.user.username), {
+            'object_id': group.name,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assert_(group in self.user.get_profile().starred_groups.all())
+
+    def test_post_watched_review_group_with_does_not_exist_error(self):
+        """Testing the POST users/<username>/watched/review-groups/ API with Does Not Exist error"""
+        rsp = self.apiPost(self.get_list_url(self.user.username), {
+            'object_id': 'invalidgroup',
+        }, expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_post_watched_review_group_with_site(self):
+        """Testing the POST users/<username>/watched/review-groups/ API with a local site"""
+        username = 'doc'
+        user = User.objects.get(username=username)
+
+        self.client.logout()
+        self.client.login(username=username, password='doc')
+
+        group = Group.objects.get(name='sitegroup',
+                                  local_site__name=self.local_site_name)
+
+        rsp = self.apiPost(self.get_list_url(username, self.local_site_name),
+                           { 'object_id': group.name, })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue(group in user.get_profile().starred_groups.all())
+
+    def test_post_watched_review_group_with_site_does_not_exist_error(self):
+        """Testing the POST users/<username>/watched/review-groups/ API with a local site and Does Not Exist error"""
+        username = 'doc'
+
+        self.client.logout()
+        self.client.login(username=username, password='doc')
+
+        rsp = self.apiPost(self.get_list_url(username, self.local_site_name),
+                           { 'object_id': 'devgroup', },
+                           expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_post_watched_review_group_with_site_no_access(self):
+        """Testing the POST users/<username>/watched/review-groups/ API with a local site and Permission Denied error"""
+        rsp = self.apiPost(self.get_list_url(self.user.username,
+                                              self.local_site_name),
+                           { 'object_id': 'devgroup', },
+                           expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+
+    def test_delete_watched_review_group(self):
+        """Testing the DELETE users/<username>/watched/review-groups/<id>/ API"""
+        # First, star it.
+        self.test_post_watched_review_group()
+
+        group = Group.objects.get(name='devgroup', local_site=None)
+
+        self.apiDelete(self.get_item_url(self.user.username, group.name))
+        self.assertFalse(group in
+                         self.user.get_profile().starred_groups.all())
+
+    def test_delete_watched_review_group_with_does_not_exist_error(self):
+        """Testing the DELETE users/<username>/watched/review-groups/<id>/ API with Does Not Exist error"""
+        rsp = self.apiDelete(self.get_item_url(self.user.username,
+                                                'invalidgroup'),
+                             expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_delete_watched_review_group_with_site(self):
+        """Testing the DELETE users/<username>/watched/review-groups/<id>/ API with a local site"""
+        self.test_post_watched_review_group_with_site()
+
+        user = User.objects.get(username='doc')
+        group = Group.objects.get(name='sitegroup',
+                                  local_site__name=self.local_site_name)
+
+        self.apiDelete(self.get_item_url(user.username, group.name,
+                                          self.local_site_name))
+        self.assertFalse(group in user.get_profile().starred_groups.all())
+
+    def test_delete_watched_review_group_with_site_no_access(self):
+        """Testing the DELETE users/<username>/watched/review-groups/<id>/ API with a local site and Permission Denied error"""
+        rsp = self.apiDelete(self.get_item_url(self.user.username, 'group',
+                                                self.local_site_name),
+                             expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_watched_review_groups(self):
+        """Testing the GET users/<username>/watched/review-groups/ API"""
+        self.test_post_watched_review_group()
+
+        rsp = self.apiGet(self.get_list_url(self.user.username))
+        self.assertEqual(rsp['stat'], 'ok')
+
+        watched = self.user.get_profile().starred_groups.all()
+        apigroups = rsp['watched_review_groups']
+
+        self.assertEqual(len(apigroups), len(watched))
+
+        for id in range(len(watched)):
+            self.assertEqual(apigroups[id]['watched_review_group']['name'],
+                             watched[id].name)
+
+    def test_get_watched_review_groups_with_site(self):
+        """Testing the GET users/<username>/watched/review-groups/ API with a local site"""
+        self.test_post_watched_review_group_with_site()
+
+        rsp = self.apiGet(self.get_list_url('doc', self.local_site_name))
+
+        watched = self.user.get_profile().starred_groups.filter(
+            local_site__name=self.local_site_name)
+        apigroups = rsp['watched_review_groups']
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        for id in range(len(watched)):
+            self.assertEqual(apigroups[id]['watched_review_group']['name'],
+                             watched[id].name)
+
+    def test_get_watched_review_groups_with_site_no_access(self):
+        """Testing the GET users/<username>/watched/review-groups/ API with a local site and Permission Denied error"""
+        watched_url = \
+            local_site_reverse('watched-review-groups-resource',
+                               local_site_name=self.local_site_name,
+                               kwargs={ 'username': self.user.username })
+
+        rsp = self.apiGet(self.get_list_url(self.user.username,
+                                             self.local_site_name),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def get_list_url(self, username, local_site_name=None):
+        return local_site_reverse('watched-review-groups-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'username': username,
+                                  })
+
+    def get_item_url(self, username, object_id, local_site_name=None):
+        return local_site_reverse('watched-review-group-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'username': username,
+                                      'watched_obj_id': object_id,
+                                  })
+
+
+class ReviewRequestResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewRequestResource API tests."""
+
+    def test_get_reviewrequests(self):
+        """Testing the GET review-requests/ API"""
+        rsp = self.apiGet(self.get_list_url())
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.public().count())
+
+    def test_get_reviewrequests_with_site(self):
+        """Testing the GET review-requests/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+
+        rsp = self.apiGet(self.get_list_url(self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.public(
+                             local_site=local_site).count())
+
+    def test_get_reviewrequests_with_site_no_access(self):
+        """Testing the GET review-requests/ API with a local site and Permission Denied error"""
+        self.apiGet(self.get_list_url(self.local_site_name),
+                    expected_status=403)
+
+    def test_get_reviewrequests_with_status(self):
+        """Testing the GET review-requests/?status= API"""
+        url = self.get_list_url()
+
+        rsp = self.apiGet(url, {'status': 'submitted'})
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.public(status='S').count())
+
+        rsp = self.apiGet(url, {'status': 'discarded'})
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.public(status='D').count())
+
+        rsp = self.apiGet(url, {'status': 'all'})
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.public(status=None).count())
+
+    def test_get_reviewrequests_with_counts_only(self):
+        """Testing the GET review-requests/?counts-only=1 API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'], ReviewRequest.objects.public().count())
+
+    def test_get_reviewrequests_with_to_groups(self):
+        """Testing the GET review-requests/?to-groups= API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'to-groups': 'devgroup',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.to_group("devgroup",
+                                                        None).count())
+
+    def test_get_reviewrequests_with_to_groups_and_status(self):
+        """Testing the GET review-requests/?to-groups=&status= API"""
+        url = self.get_list_url()
+
+        rsp = self.apiGet(url, {
+            'status': 'submitted',
+            'to-groups': 'devgroup',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.to_group("devgroup", None,
+                                           status='S').count())
+
+        rsp = self.apiGet(url, {
+            'status': 'discarded',
+            'to-groups': 'devgroup',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.to_group("devgroup", None,
+                                           status='D').count())
+
+    def test_get_reviewrequests_with_to_groups_and_counts_only(self):
+        """Testing the GET review-requests/?to-groups=&counts-only=1 API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'to-groups': 'devgroup',
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         ReviewRequest.objects.to_group("devgroup",
+                                                        None).count())
+
+    def test_get_reviewrequests_with_to_users(self):
+        """Testing the GET review-requests/?to-users= API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'to-users': 'grumpy',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.to_user("grumpy").count())
+
+    def test_get_reviewrequests_with_to_users_and_status(self):
+        """Testing the GET review-requests/?to-users=&status= API"""
+        url = self.get_list_url()
+
+        rsp = self.apiGet(url, {
+            'status': 'submitted',
+            'to-users': 'grumpy',
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.to_user("grumpy", status='S').count())
+
+        rsp = self.apiGet(url, {
+            'status': 'discarded',
+            'to-users': 'grumpy',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.to_user("grumpy", status='D').count())
+
+    def test_get_reviewrequests_with_to_users_and_counts_only(self):
+        """Testing the GET review-requests/?to-users=&counts-only=1 API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'to-users': 'grumpy',
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         ReviewRequest.objects.to_user("grumpy").count())
+
+    def test_get_reviewrequests_with_to_users_directly(self):
+        """Testing the GET review-requests/?to-users-directly= API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'to-users-directly': 'doc',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.to_user_directly("doc").count())
+
+    def test_get_reviewrequests_with_to_users_directly_and_status(self):
+        """Testing the GET review-requests/?to-users-directly=&status= API"""
+        url = self.get_list_url()
+
+        rsp = self.apiGet(url, {
+            'status': 'submitted',
+            'to-users-directly': 'doc'
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.to_user_directly("doc", status='S').count())
+
+        rsp = self.apiGet(url, {
+            'status': 'discarded',
+            'to-users-directly': 'doc'
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.to_user_directly("doc", status='D').count())
+
+    def test_get_reviewrequests_with_to_users_directly_and_counts_only(self):
+        """Testing the GET review-requests/?to-users-directly=&counts-only=1 API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'to-users-directly': 'doc',
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         ReviewRequest.objects.to_user_directly("doc").count())
+
+    def test_get_reviewrequests_with_from_user(self):
+        """Testing the GET review-requests/?from-user= API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'from-user': 'grumpy',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+                         ReviewRequest.objects.from_user("grumpy").count())
+
+    def test_get_reviewrequests_with_from_user_and_status(self):
+        """Testing the GET review-requests/?from-user=&status= API"""
+        url = self.get_list_url()
+
+        rsp = self.apiGet(url, {
+            'status': 'submitted',
+            'from-user': 'grumpy',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.from_user("grumpy", status='S').count())
+
+        rsp = self.apiGet(url, {
+            'status': 'discarded',
+            'from-user': 'grumpy',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']),
+            ReviewRequest.objects.from_user("grumpy", status='D').count())
+
+    def test_get_reviewrequests_with_from_user_and_counts_only(self):
+        """Testing the GET review-requests/?from-user=&counts-only=1 API"""
+        rsp = self.apiGet(self.get_list_url(), {
+            'from-user': 'grumpy',
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         ReviewRequest.objects.from_user("grumpy").count())
+
+    def test_get_reviewrequests_with_time_added_from(self):
+        """Testing the GET review-requests/?time-added-from= API"""
+        start_index = 3
+
+        public_review_requests = \
+            ReviewRequest.objects.public().order_by('time_added')
+        r = public_review_requests[start_index]
+        timestamp = r.time_added.isoformat()
+
+        rsp = self.apiGet(self.get_list_url(), {
+            'time-added-from': timestamp,
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         public_review_requests.count() - start_index)
+        self.assertEqual(rsp['count'],
+                         public_review_requests.filter(
+                            time_added__gte=r.time_added).count())
+
+    def test_get_reviewrequests_with_time_added_to(self):
+        """Testing the GET review-requests/?time-added-to= API"""
+        start_index = 3
+
+        public_review_requests = \
+            ReviewRequest.objects.public().order_by('time_added')
+        r = public_review_requests[start_index]
+        timestamp = r.time_added.isoformat()
+
+        rsp = self.apiGet(self.get_list_url(), {
+            'time-added-to': timestamp,
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         public_review_requests.count() - start_index + 1)
+        self.assertEqual(rsp['count'],
+                         public_review_requests.filter(
+                             time_added__lt=r.time_added).count())
+
+    def test_get_reviewrequests_with_last_updated_from(self):
+        """Testing the GET review-requests/?last-updated-from= API"""
+        start_index = 3
+
+        public_review_requests = \
+            ReviewRequest.objects.public().order_by('last_updated')
+        r = public_review_requests[start_index]
+        timestamp = r.last_updated.isoformat()
+
+        rsp = self.apiGet(self.get_list_url(), {
+            'last-updated-from': timestamp,
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         public_review_requests.count() - start_index)
+        self.assertEqual(rsp['count'],
+                         public_review_requests.filter(
+                             last_updated__gte=r.last_updated).count())
+
+    def test_get_reviewrequests_with_last_updated_to(self):
+        """Testing the GET review-requests/?last-updated-to= API"""
+        start_index = 3
+
+        public_review_requests = \
+            ReviewRequest.objects.public().order_by('last_updated')
+        r = public_review_requests[start_index]
+        timestamp = r.last_updated.isoformat()
+
+        rsp = self.apiGet(self.get_list_url(), {
+            'last-updated-to': timestamp,
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'],
+                         public_review_requests.count() - start_index + 1)
+        self.assertEqual(rsp['count'],
+                         public_review_requests.filter(
+                             last_updated__lt=r.last_updated).count())
+
+    def test_post_reviewrequests(self):
+        """Testing the POST review-requests/ API"""
+        rsp = self.apiPost(self.get_list_url(), {
+            'repository': self.repository.path,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(
+            rsp['review_request']['links']['repository']['href'],
+            self.base_url +
+            RepositoryResourceTests.get_item_url(self.repository.id))
+
+        # See if we can fetch this. Also return it for use in other
+        # unit tests.
+        return ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+    def test_post_reviewrequests_with_site(self):
+        """Testing the POST review-requests/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        repository = Repository.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        rsp = self.apiPost(self.get_list_url(self.local_site_name),
+                           { 'repository': repository.path, })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['review_request']['links']['repository']['title'],
+                         repository.name)
+
+    def test_post_reviewrequests_with_site_no_access(self):
+        """Testing the POST review-requests/ API with a local site and Permission Denied error"""
+        repository = Repository.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        self.apiPost(self.get_list_url(self.local_site_name),
+                     { 'repository': repository.path, },
+                     expected_status=403)
+
+    def test_post_reviewrequests_with_site_invalid_repository_error(self):
+        """Testing the POST review-requests/ API with a local site and Invalid Repository error"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiPost(self.get_list_url(self.local_site_name),
+                           { 'repository': self.repository.path, },
+                           expected_status=400)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], INVALID_REPOSITORY.code)
+
+    def test_post_reviewrequests_with_invalid_repository_error(self):
+        """Testing the POST review-requests/ API with Invalid Repository error"""
+        rsp = self.apiPost(self.get_list_url(), {
+            'repository': 'gobbledygook',
+        }, expected_status=400)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], INVALID_REPOSITORY.code)
+
+    def test_post_reviewrequests_with_no_site_invalid_repository_error(self):
+        """Testing the POST review-requests/ API with Invalid Repository error from a site-local repository"""
+        repository = Repository.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        rsp = self.apiPost(self.get_list_url(), {
+            'repository': repository.path,
+        }, expected_status=400)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], INVALID_REPOSITORY.code)
+
+    def test_post_reviewrequests_with_submit_as(self):
+        """Testing the POST review-requests/?submit_as= API"""
+        self.user.is_superuser = True
+        self.user.save()
+
+        rsp = self.apiPost(self.get_list_url(), {
+            'repository': self.repository.path,
+            'submit_as': 'doc',
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(
+            rsp['review_request']['links']['repository']['href'],
+            self.base_url +
+            RepositoryResourceTests.get_item_url(self.repository.id))
+        self.assertEqual(
+            rsp['review_request']['links']['submitter']['href'],
+            self.base_url +
+            UserResourceTests.get_item_url('doc'))
+
+        ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+    def test_post_reviewrequests_with_submit_as_and_permission_denied_error(self):
+        """Testing the POST review-requests/?submit_as= API with Permission Denied error"""
+        rsp = self.apiPost(self.get_list_url(), {
+            'repository': self.repository.path,
+            'submit_as': 'doc',
+        }, expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_put_reviewrequest_status_discarded(self):
+        """Testing the PUT review-requests/<id>/?status=discarded API"""
+        r = ReviewRequest.objects.filter(public=True, status='P',
+                                         submitter=self.user)[0]
+
+        rsp = self.apiPut(self.get_item_url(r.display_id), {
+            'status': 'discarded',
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        r = ReviewRequest.objects.get(pk=r.id)
+        self.assertEqual(r.status, 'D')
+
+    def test_put_reviewrequest_status_pending(self):
+        """Testing the PUT review-requests/<id>/?status=pending API"""
+        r = ReviewRequest.objects.filter(public=True, status='P',
+                                         submitter=self.user)[0]
+        r.close(ReviewRequest.SUBMITTED)
+        r.save()
+
+        rsp = self.apiPut(self.get_item_url(r.display_id), {
+            'status': 'pending',
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        r = ReviewRequest.objects.get(pk=r.id)
+        self.assertEqual(r.status, 'P')
+
+    def test_put_reviewrequest_status_submitted(self):
+        """Testing the PUT review-requests/<id>/?status=submitted API"""
+        r = ReviewRequest.objects.filter(public=True, status='P',
+                                         submitter=self.user)[0]
+
+        rsp = self.apiPut(self.get_item_url(r.display_id), {
+            'status': 'submitted',
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        r = ReviewRequest.objects.get(pk=r.id)
+        self.assertEqual(r.status, 'S')
+
+    def test_put_reviewrequest_status_submitted_with_site(self):
+        """Testing the PUT review-requests/<id>/?status=submitted API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        r = ReviewRequest.objects.filter(public=True, status='P',
+                                         submitter__username='doc',
+                                         local_site__name=self.local_site_name)[0]
+
+        rsp = self.apiPut(self.get_item_url(r.display_id,
+                                            self.local_site_name),
+                          { 'status': 'submitted' })
+        self.assertEqual(rsp['stat'], 'ok')
+
+        r = ReviewRequest.objects.get(pk=r.id)
+        self.assertEqual(r.status, 'S')
+
+    def test_put_reviewrequest_status_submitted_with_site_no_access(self):
+        """Testing the PUT review-requests/<id>/?status=submitted API with a local site and Permission Denied error"""
+        r = ReviewRequest.objects.filter(public=True, status='P',
+                                         submitter__username='doc',
+                                         local_site__name=self.local_site_name)[0]
+
+        self.apiPut(self.get_item_url(r.display_id, self.local_site_name),
+                    { 'status': 'submitted' },
+                    expected_status=403)
+
+    def test_get_reviewrequest(self):
+        """Testing the GET review-requests/<id>/ API"""
+        review_request = ReviewRequest.objects.public()[0]
+
+        rsp = self.apiGet(self.get_item_url(review_request.display_id))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['review_request']['id'], review_request.display_id)
+        self.assertEqual(rsp['review_request']['summary'],
+                         review_request.summary)
+
+    def test_get_reviewrequest_with_site(self):
+        """Testing the GET review-requests/<id>/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+
+        rsp = self.apiGet(self.get_item_url(review_request.display_id,
+                                            self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['review_request']['id'],
+                         review_request.display_id)
+        self.assertEqual(rsp['review_request']['summary'],
+                         review_request.summary)
+
+    def test_get_reviewrequest_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/ API with a local site and Permission Denied error"""
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+
+        self.apiGet(self.get_item_url(review_request.display_id,
+                                      self.local_site_name),
+                    expected_status=403)
+
+    def test_get_reviewrequest_with_non_public_and_permission_denied_error(self):
+        """Testing the GET review-requests/<id>/ API with non-public and Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(public=False,
+            local_site=None).exclude(submitter=self.user)[0]
+
+        rsp = self.apiGet(self.get_item_url(review_request.display_id),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_reviewrequest_with_invite_only_group_and_permission_denied_error(self):
+        """Testing the GET review-requests/<id>/ API with invite-only group and Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(public=True,
+            local_site=None).exclude(submitter=self.user)[0]
+        review_request.target_groups.clear()
+        review_request.target_people.clear()
+
+        group = Group(name='test-group', invite_only=True)
+        group.save()
+
+        review_request.target_groups.add(group)
+        review_request.save()
+
+        rsp = self.apiGet(self.get_item_url(review_request.display_id),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_reviewrequest_with_invite_only_group_and_target_user(self):
+        """Testing the GET review-requests/<id>/ API with invite-only group and target user"""
+        review_request = ReviewRequest.objects.filter(public=True,
+            local_site=None).exclude(submitter=self.user)[0]
+        review_request.target_groups.clear()
+        review_request.target_people.clear()
+
+        group = Group(name='test-group', invite_only=True)
+        group.save()
+
+        review_request.target_groups.add(group)
+        review_request.target_people.add(self.user)
+        review_request.save()
+
+        rsp = self.apiGet(self.get_item_url(review_request.display_id))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['review_request']['id'], review_request.display_id)
+        self.assertEqual(rsp['review_request']['summary'],
+                         review_request.summary)
+
+    def test_get_reviewrequest_with_repository_and_changenum(self):
+        """Testing the GET review-requests/?repository=&changenum= API"""
+        review_request = \
+            ReviewRequest.objects.filter(changenum__isnull=False)[0]
+
+        rsp = self.apiGet(self.get_list_url(), {
+            'repository': review_request.repository.id,
+            'changenum': review_request.changenum,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['review_requests']), 1)
+        self.assertEqual(rsp['review_requests'][0]['id'],
+                         review_request.display_id)
+        self.assertEqual(rsp['review_requests'][0]['summary'],
+                         review_request.summary)
+        self.assertEqual(rsp['review_requests'][0]['changenum'],
+                         review_request.changenum)
+
+    def test_delete_reviewrequest(self):
+        """Testing the DELETE review-requests/<id>/ API"""
+        self.user.user_permissions.add(
+            Permission.objects.get(codename='delete_reviewrequest'))
+        self.user.save()
+        self.assert_(self.user.has_perm('reviews.delete_reviewrequest'))
+
+        review_request = ReviewRequest.objects.from_user(self.user.username)[0]
+
+        rsp = self.apiDelete(self.get_item_url(review_request.display_id))
+        self.assertEqual(rsp, None)
+        self.assertRaises(ReviewRequest.DoesNotExist,
+                          ReviewRequest.objects.get,
+                          pk=review_request.pk)
+
+    def test_delete_reviewrequest_with_permission_denied_error(self):
+        """Testing the DELETE review-requests/<id>/ API with Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(
+            local_site=None).exclude(submitter=self.user)[0]
+
+        rsp = self.apiDelete(self.get_item_url(review_request.display_id),
+                             expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_delete_reviewrequest_with_does_not_exist_error(self):
+        """Testing the DELETE review-requests/<id>/ API with Does Not Exist error"""
+        self.user.user_permissions.add(
+            Permission.objects.get(codename='delete_reviewrequest'))
+        self.user.save()
+        self.assert_(self.user.has_perm('reviews.delete_reviewrequest'))
+
+        rsp = self.apiDelete(self.get_item_url(999), expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_delete_reviewrequest_with_site(self):
+        """Testing the DELETE review-requests/<id>/ API with a lotal site"""
+        user = User.objects.get(username='doc')
+        user.user_permissions.add(
+            Permission.objects.get(codename='delete_reviewrequest'))
+        user.save()
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.filter(local_site=local_site,
+            submitter__username='doc')[0]
+
+        rsp = self.apiDelete(self.get_item_url(review_request.display_id,
+                                                self.local_site_name))
+        self.assertEqual(rsp, None)
+        self.assertRaises(ReviewRequest.DoesNotExist,
+                          ReviewRequest.objects.get, pk=review_request.pk)
+
+    @classmethod
+    def get_list_url(cls, local_site_name=None):
+        return local_site_reverse('review-requests-resource',
+                                  local_site_name=local_site_name)
+
+    def get_item_url(self, review_request_id, local_site_name=None):
+        return local_site_reverse('review-request-resource',
+                                  local_site_name=local_site_name,
+                                  kwargs={
+                                      'review_request_id': review_request_id,
+                                  })
+
+
+class ReviewRequestDraftResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewRequestDraftResource API tests."""
+
+    def _create_update_review_request(self, apiFunc, expected_status,
+                                      review_request=None,
+                                      local_site_name=None):
+        summary = "My Summary"
+        description = "My Description"
+        testing_done = "My Testing Done"
+        branch = "My Branch"
+        bugs = "#123,456"
+
+        if review_request is None:
+            review_request = \
+                ReviewRequest.objects.from_user(self.user.username)[0]
+
+        func_kwargs = {
+            'summary': summary,
+            'description': description,
+            'testing_done': testing_done,
+            'branch': branch,
+            'bugs_closed': bugs,
+        }
+
+        rsp = apiFunc(self.get_url(review_request, local_site_name),
+                      func_kwargs,
+                      expected_status=expected_status)
+
+        if expected_status >= 200 and expected_status < 300:
+            self.assertEqual(rsp['stat'], 'ok')
+            self.assertEqual(rsp['draft']['summary'], summary)
+            self.assertEqual(rsp['draft']['description'], description)
+            self.assertEqual(rsp['draft']['testing_done'], testing_done)
+            self.assertEqual(rsp['draft']['branch'], branch)
+            self.assertEqual(rsp['draft']['bugs_closed'], ['123', '456'])
+
+            draft = ReviewRequestDraft.objects.get(pk=rsp['draft']['id'])
+            self.assertEqual(draft.summary, summary)
+            self.assertEqual(draft.description, description)
+            self.assertEqual(draft.testing_done, testing_done)
+            self.assertEqual(draft.branch, branch)
+            self.assertEqual(draft.get_bug_list(), ['123', '456'])
+
+        return rsp
+
+    def _create_update_review_request_with_site(self, apiFunc, expected_status,
+                                                relogin=True,
+                                                review_request=None):
+        if relogin:
+            self.client.logout()
+            self.client.login(username='doc', password='doc')
+
+        if review_request is None:
+            review_request = ReviewRequest.objects.from_user('doc',
+                local_site=LocalSite.objects.get(name=self.local_site_name))[0]
+
+        return self._create_update_review_request(
+            apiFunc, expected_status, review_request, self.local_site_name)
+
+    def test_put_reviewrequestdraft(self):
+        """Testing the PUT review-requests/<id>/draft/ API"""
+        self._create_update_review_request(self.apiPut, 200)
+
+    def test_put_reviewrequestdraft_with_site(self):
+        """Testing the PUT review-requests/<id>/draft/ API with a local site"""
+        self._create_update_review_request_with_site(self.apiPut, 200)
+
+    def test_put_reviewrequestdraft_with_site_no_access(self):
+        """Testing the PUT review-requests/<id>/draft/ API with a local site and Permission Denied error"""
+        rsp = self._create_update_review_request_with_site(
+            self.apiPut, 403, relogin=False)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_post_reviewrequestdraft(self):
+        """Testing the POST review-requests/<id>/draft/ API"""
+        self._create_update_review_request(self.apiPost, 201)
+
+    def test_post_reviewrequestdraft_with_site(self):
+        """Testing the POST review-requests/<id>/draft/ API with a local site"""
+        self._create_update_review_request_with_site(self.apiPost, 201)
+
+    def test_post_reviewrequestdraft_with_site_no_access(self):
+        """Testing the POST review-requests/<id>/draft/ API with a local site and Permission Denied error"""
+        rsp = self._create_update_review_request_with_site(
+            self.apiPost, 403, relogin=False)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_put_reviewrequestdraft_with_changedesc(self):
+        """Testing the PUT review-requests/<id>/draft/ API with a change description"""
+        changedesc = 'This is a test change description.'
+        review_request = ReviewRequest.objects.create(self.user,
+                                                      self.repository)
+        review_request.publish(self.user)
+
+        rsp = self.apiPost(self.get_url(review_request), {
+            'changedescription': changedesc,
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['draft']['changedescription'], changedesc)
+
+        draft = ReviewRequestDraft.objects.get(pk=rsp['draft']['id'])
+        self.assertNotEqual(draft.changedesc, None)
+        self.assertEqual(draft.changedesc.text, changedesc)
+
+    def test_put_reviewrequestdraft_with_invalid_field_name(self):
+        """Testing the PUT review-requests/<id>/draft/ API with Invalid Form Data error"""
+        review_request = ReviewRequest.objects.from_user(self.user.username)[0]
+
+        rsp = self.apiPut(self.get_url(review_request), {
+            'foobar': 'foo',
+        }, 400)
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], INVALID_FORM_DATA.code)
+        self.assertTrue('foobar' in rsp['fields'])
+
+    def test_put_reviewrequestdraft_with_permission_denied_error(self):
+        """Testing the PUT review-requests/<id>/draft/ API with Permission Denied error"""
+        bugs_closed = '123,456'
+        review_request = ReviewRequest.objects.from_user('admin')[0]
+
+        rsp = self.apiPut(self.get_url(review_request), {
+            'bugs_closed': bugs_closed,
+        }, 403)
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_put_reviewrequestdraft_publish(self):
+        """Testing the PUT review-requests/<id>/draft/?public=1 API"""
+        # Set some data first.
+        self.test_put_reviewrequestdraft()
+
+        review_request = ReviewRequest.objects.from_user(self.user.username)[0]
+
+        rsp = self.apiPut(self.get_url(review_request), {
+            'public': True,
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        review_request = ReviewRequest.objects.get(pk=review_request.id)
+        self.assertEqual(review_request.summary, "My Summary")
+        self.assertEqual(review_request.description, "My Description")
+        self.assertEqual(review_request.testing_done, "My Testing Done")
+        self.assertEqual(review_request.branch, "My Branch")
+        self.assertTrue(review_request.public)
+
+        self.assertEqual(len(mail.outbox), 1)
+        self.assertEqual(mail.outbox[0].subject, "Review Request: My Summary")
+        self.assertValidRecipients(["doc", "grumpy"], [])
+
+    def test_put_reviewrequestdraft_publish_with_new_review_request(self):
+        """Testing the PUT review-requests/<id>/draft/?public=1 API with a new review request"""
+        # Set some data first.
+        review_request = ReviewRequest.objects.create(self.user,
+                                                      self.repository)
+        review_request.target_people = [
+            User.objects.get(username='doc')
+        ]
+        review_request.save()
+
+        self._create_update_review_request(self.apiPut, 200, review_request)
+
+        rsp = self.apiPut(self.get_url(review_request), {
+            'public': True,
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        review_request = ReviewRequest.objects.get(pk=review_request.id)
+        self.assertEqual(review_request.summary, "My Summary")
+        self.assertEqual(review_request.description, "My Description")
+        self.assertEqual(review_request.testing_done, "My Testing Done")
+        self.assertEqual(review_request.branch, "My Branch")
+        self.assertTrue(review_request.public)
+
+        self.assertEqual(len(mail.outbox), 1)
+        self.assertEqual(mail.outbox[0].subject, "Review Request: My Summary")
+        self.assertValidRecipients(["doc", "grumpy"], [])
+
+    def test_delete_reviewrequestdraft(self):
+        """Testing the DELETE review-requests/<id>/draft/ API"""
+        review_request = ReviewRequest.objects.from_user(self.user.username)[0]
+        summary = review_request.summary
+        description = review_request.description
+
+        # Set some data.
+        self.test_put_reviewrequestdraft()
+
+        self.apiDelete(self.get_url(review_request))
+
+        review_request = ReviewRequest.objects.get(pk=review_request.id)
+        self.assertEqual(review_request.summary, summary)
+        self.assertEqual(review_request.description, description)
+
+    def test_delete_reviewrequestdraft_with_site(self):
+        """Testing the DELETE review-requests/<id>/draft/ API with a local site"""
+        review_request = ReviewRequest.objects.from_user('doc',
+            local_site=LocalSite.objects.get(name=self.local_site_name))[0]
+        summary = review_request.summary
+        description = review_request.description
+
+        self.test_put_reviewrequestdraft_with_site()
+
+        self.apiDelete(self.get_url(review_request, self.local_site_name))
+
+        review_request = ReviewRequest.objects.get(pk=review_request.id)
+        self.assertEqual(review_request.summary, summary)
+        self.assertEqual(review_request.description, description)
+
+    def test_delete_reviewrequestdraft_with_site_no_access(self):
+        """Testing the DELETE review-requests/<id>/draft/ API with a local site and Permission Denied error"""
+        review_request = ReviewRequest.objects.from_user('doc',
+            local_site=LocalSite.objects.get(name=self.local_site_name))[0]
+        rsp = self.apiDelete(
+            self.get_url(review_request, self.local_site_name),
+            expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def get_url(self, review_request, local_site_name=None):
+        return local_site_reverse(
+            'draft-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+            })
+
+
+class ReviewResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewResource APIs."""
+
+    def test_get_reviews(self):
+        """Testing the GET review-requests/<id>/reviews/ API"""
+        review_request = Review.objects.filter()[0].review_request
+        rsp = self.apiGet(self.get_list_url(review_request))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['reviews']), review_request.reviews.count())
+
+    def test_get_reviews_with_site(self):
+        """Testing the GET review-requests/<id>/reviews/ API with a local site"""
+        self.test_post_reviews_with_site(public=True)
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+
+        rsp = self.apiGet(self.get_list_url(review_request,
+                                            self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['reviews']), review_request.reviews.count())
+
+    def test_get_reviews_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/reviews/ API with a local site and Permission Denied error"""
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+        rsp = self.apiGet(self.get_list_url(review_request,
+                                            self.local_site_name),
+                          expected_status=403)
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_reviews_with_counts_only(self):
+        """Testing the GET review-requests/<id>/reviews/?counts-only=1 API"""
+        review_request = Review.objects.all()[0].review_request
+        rsp = self.apiGet(self.get_list_url(review_request), {
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'], review_request.reviews.count())
+
+    def test_post_reviews(self):
+        """Testing the POST review-requests/<id>/reviews/ API"""
+        body_top = ""
+        body_bottom = "My Body Bottom"
+        ship_it = True
+
+        # Clear out any reviews on the first review request we find.
+        review_request = ReviewRequest.objects.public(local_site=None)[0]
+        review_request.reviews = []
+        review_request.save()
+
+        rsp, response = self.api_post_with_response(
+            self.get_list_url(review_request),
+            {
+                'ship_it': ship_it,
+                'body_top': body_top,
+                'body_bottom': body_bottom,
+            })
+
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('Location' in response)
+
+        reviews = review_request.reviews.filter(user=self.user)
+        self.assertEqual(len(reviews), 1)
+        review = reviews[0]
+
+        self.assertEqual(response['Location'],
+                         self.base_url +
+                         self.get_item_url(review_request, review.id))
+
+        self.assertEqual(review.ship_it, ship_it)
+        self.assertEqual(review.body_top, body_top)
+        self.assertEqual(review.body_bottom, body_bottom)
+        self.assertEqual(review.public, False)
+
+        self.assertEqual(len(mail.outbox), 0)
+
+    def test_post_reviews_with_site(self, public=False):
+        """Testing the POST review-requests/<id>/reviews/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        body_top = ""
+        body_bottom = "My Body Bottom"
+        ship_it = True
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+
+        # Clear out any reviews on the first review request we find.
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+        review_request.reviews = []
+        review_request.save()
+
+        post_data = {
+            'ship_it': ship_it,
+            'body_top': body_top,
+            'body_bottom': body_bottom,
+            'public': public,
+        }
+
+        rsp, response = self.api_post_with_response(
+            self.get_list_url(review_request, self.local_site_name),
+            post_data)
+
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('Location' in response)
+
+        reviews = review_request.reviews.all()
+        self.assertEqual(len(reviews), 1)
+        review = reviews[0]
+
+        self.assertEqual(rsp['review']['id'], review.id)
+
+        self.assertEqual(review.ship_it, ship_it)
+        self.assertEqual(review.body_top, body_top)
+        self.assertEqual(review.body_bottom, body_bottom)
+        self.assertEqual(review.public, public)
+
+        if public:
+            self.assertEqual(len(mail.outbox), 1)
+        else:
+            self.assertEqual(len(mail.outbox), 0)
+
+    def test_post_reviews_with_site_no_access(self):
+        """Testing the POST review-requests/<id>/reviews/ API with a local site and Permission Denied error"""
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+
+        rsp = self.apiPost(self.get_list_url(review_request,
+                                             self.local_site_name),
+                           expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_put_review(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/ API"""
+        body_top = ""
+        body_bottom = "My Body Bottom"
+        ship_it = True
+
+        # Clear out any reviews on the first review request we find.
+        review_request = ReviewRequest.objects.public(local_site=None)[0]
+        review_request.reviews = []
+        review_request.save()
+
+        rsp, response = self.api_post_with_response(
+            self.get_list_url(review_request))
+
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('Location' in response)
+
+        review_url = response['Location']
+
+        rsp = self.apiPut(review_url, {
+            'ship_it': ship_it,
+            'body_top': body_top,
+            'body_bottom': body_bottom,
+        })
+
+        reviews = review_request.reviews.filter(user=self.user)
+        self.assertEqual(len(reviews), 1)
+        review = reviews[0]
+
+        self.assertEqual(review.ship_it, ship_it)
+        self.assertEqual(review.body_top, body_top)
+        self.assertEqual(review.body_bottom, body_bottom)
+        self.assertEqual(review.public, False)
+
+        self.assertEqual(len(mail.outbox), 0)
+
+        # Make this easy to use in other tests.
+        return review
+
+    def test_put_review_with_site(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        body_top = ""
+        body_bottom = "My Body Bottom"
+        ship_it = True
+
+        # Clear out any reviews on the first review request we find.
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+        review_request.reviews = []
+        review_request.save()
+
+        rsp, response = self.api_post_with_response(
+            self.get_list_url(review_request, self.local_site_name))
+
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('Location' in response)
+
+        review_url = response['Location']
+
+        rsp = self.apiPut(review_url, {
+            'ship_it': ship_it,
+            'body_top': body_top,
+            'body_bottom': body_bottom,
+        })
+
+        reviews = review_request.reviews.filter(user__username='doc')
+        self.assertEqual(len(reviews), 1)
+        review = reviews[0]
+
+        self.assertEqual(review.ship_it, ship_it)
+        self.assertEqual(review.body_top, body_top)
+        self.assertEqual(review.body_bottom, body_bottom)
+        self.assertEqual(review.public, False)
+
+        self.assertEqual(len(mail.outbox), 0)
+
+        # Make this easy to use in other tests.
+        return review
+
+    def test_put_review_with_site_no_access(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/ API with a local site and Permission Denied error"""
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.save()
+
+        rsp = self.apiPut(self.get_item_url(review_request, review.id,
+                                            self.local_site_name),
+                          { 'ship_it': True, },
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_put_review_with_published_review(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/ API with pre-published review"""
+        review = Review.objects.filter(user=self.user, public=True,
+                                       base_reply_to__isnull=True)[0]
+
+        self.apiPut(self.get_item_url(review.review_request, review.id), {
+            'ship_it': True,
+        }, expected_status=403)
+
+    def test_put_review_publish(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/?public=1 API"""
+        body_top = "My Body Top"
+        body_bottom = ""
+        ship_it = True
+
+        # Clear out any reviews on the first review request we find.
+        review_request = ReviewRequest.objects.public()[0]
+        review_request.reviews = []
+        review_request.save()
+
+        rsp, response = \
+            self.api_post_with_response(self.get_list_url(review_request))
+
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('Location' in response)
+
+        review_url = response['Location']
+
+        rsp = self.apiPut(review_url, {
+            'public': True,
+            'ship_it': ship_it,
+            'body_top': body_top,
+            'body_bottom': body_bottom,
+        })
+
+        reviews = review_request.reviews.filter(user=self.user)
+        self.assertEqual(len(reviews), 1)
+        review = reviews[0]
+
+        self.assertEqual(review.ship_it, ship_it)
+        self.assertEqual(review.body_top, body_top)
+        self.assertEqual(review.body_bottom, body_bottom)
+        self.assertEqual(review.public, True)
+
+        self.assertEqual(len(mail.outbox), 1)
+        self.assertEqual(mail.outbox[0].subject,
+                         "Re: Review Request: Interdiff Revision Test")
+        self.assertValidRecipients(["admin", "grumpy"], [])
+
+    def test_delete_review(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/ API"""
+        # Set up the draft to delete.
+        review = self.test_put_review()
+        review_request = review.review_request
+
+        self.apiDelete(self.get_item_url(review_request, review.id))
+        self.assertEqual(review_request.reviews.count(), 0)
+
+    def test_delete_review_with_permission_denied(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/ API with Permission Denied error"""
+        # Set up the draft to delete.
+        review = self.test_put_review()
+        review.user = User.objects.get(username='doc')
+        review.save()
+
+        review_request = review.review_request
+        old_count = review_request.reviews.count()
+
+        self.apiDelete(self.get_item_url(review_request, review.id),
+                       expected_status=403)
+        self.assertEqual(review_request.reviews.count(), old_count)
+
+    def test_delete_review_with_published_review(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/ API with pre-published review"""
+        review = Review.objects.filter(user=self.user, public=True,
+                                       base_reply_to__isnull=True)[0]
+        review_request = review.review_request
+        old_count = review_request.reviews.count()
+
+        self.apiDelete(self.get_item_url(review_request, review.id),
+                       expected_status=403)
+        self.assertEqual(review_request.reviews.count(), old_count)
+
+    def test_delete_review_with_does_not_exist(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/ API with Does Not Exist error"""
+        review_request = ReviewRequest.objects.public()[0]
+        rsp = self.apiDelete(self.get_item_url(review_request, 919239),
+                             expected_status=404)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], DOES_NOT_EXIST.code)
+
+    def test_delete_review_with_local_site(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/ API with a local site"""
+        review = self.test_put_review_with_site()
+
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+
+        self.apiDelete(self.get_item_url(review_request, review.id,
+                                          self.local_site_name))
+        self.assertEqual(review_request.reviews.count(), 0)
+
+    def test_delete_review_with_local_site_no_access(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/ API with a local site and Permission Denied error"""
+        local_site = LocalSite.objects.get(name=self.local_site_name)
+        review_request = ReviewRequest.objects.public(local_site=local_site)[0]
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.save()
+
+        rsp = self.apiDelete(self.get_item_url(review_request, review.id,
+                                                self.local_site_name),
+                             expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    @classmethod
+    def get_list_url(cls, review_request, local_site_name=None):
+        return local_site_reverse(
+            'reviews-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+            })
+
+    def get_item_url(self, review_request, review_id, local_site_name=None):
+        return local_site_reverse(
+            'review-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+                'review_id': review_id,
+            })
+
+
+class ReviewCommentResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewCommentResource APIs."""
+    def test_get_diff_comments(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/diff-comments/ API"""
+        review = Review.objects.filter(comments__pk__gt=0)[0]
+
+        rsp = self.apiGet(self.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['diff_comments']), review.comments.count())
+
+    def test_get_diff_comments_with_counts_only(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/diff-comments/?counts-only=1 API"""
+        review = Review.objects.filter(comments__pk__gt=0)[0]
+
+        rsp = self.apiGet(self.get_list_url(review), {
+            'counts-only': 1,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'], review.comments.count())
+
+    def test_get_diff_comments_with_site(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/diff-comments/ API with a local site"""
+        review_id = self.test_post_diff_comments_with_site()
+        review = Review.objects.get(pk=review_id)
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        rsp = self.apiGet(self.get_list_url(review, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['diff_comments']), review.comments.count())
+
+    def test_get_diff_comments_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/diff-comments/ API with a local site and Permission Denied error"""
+        review_id = self.test_post_diff_comments_with_site()
+        review = Review.objects.get(pk=review_id)
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiGet(self.get_list_url(review, self.local_site_name),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_post_diff_comments(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/diff-comments/ API"""
+        diff_comment_text = "Test diff comment"
+
+        # Post the review request
+        rsp = self._postNewReviewRequest()
+        review_request = ReviewRequest.objects.get(
+            pk=rsp['review_request']['id'])
+
+        # Post the diff.
+        rsp = self._postNewDiff(review_request)
+        DiffSet.objects.get(pk=rsp['diff']['id'])
+
+        # Make these public.
+        review_request.publish(self.user)
+
+        rsp = self.apiPost(ReviewResourceTests.get_list_url(review_request))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+
+        self._postNewDiffComment(review_request, review_id, diff_comment_text)
+        review = Review.objects.get(pk=review_id)
+
+        rsp = self.apiGet(self.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('diff_comments' in rsp)
+        self.assertEqual(len(rsp['diff_comments']), 1)
+        self.assertEqual(rsp['diff_comments'][0]['text'], diff_comment_text)
+
+    def test_post_diff_comments_with_site(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/diff-comments/ API with a local site"""
+        diff_comment_text = "Test diff comment"
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiPost(
+            ReviewResourceTests.get_list_url(review_request,
+                                             self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+
+        self._postNewDiffComment(review_request, review_id, diff_comment_text)
+        review = Review.objects.get(pk=review_id)
+
+        rsp = self.apiGet(self.get_list_url(review, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('diff_comments' in rsp)
+        self.assertEqual(len(rsp['diff_comments']), 1)
+        self.assertEqual(rsp['diff_comments'][0]['text'], diff_comment_text)
+
+        return review_id
+
+    def test_post_diff_comments_with_site_no_access(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/diff-comments/ API with a local site and Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.save()
+
+        rsp = self.apiPost(self.get_list_url(review, self.local_site_name),
+                           {},
+                           expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+
+    def test_post_diff_comments_with_interdiff(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/diff-comments/ API with interdiff"""
+        comment_text = "Test diff comment"
+
+        rsp, review_request_id, review_id, interdiff_revision = \
+            self._common_post_interdiff_comments(comment_text)
+
+        review_request = ReviewRequest.objects.get(pk=review_request_id)
+        review = Review.objects.get(pk=review_id)
+
+        rsp = self.apiGet(self.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('diff_comments' in rsp)
+        self.assertEqual(len(rsp['diff_comments']), 1)
+        self.assertEqual(rsp['diff_comments'][0]['text'], comment_text)
+
+    def test_get_diff_comments_with_interdiff(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/diff-comments/ API with interdiff"""
+        comment_text = "Test diff comment"
+
+        rsp, review_request_id, review_id, interdiff_revision = \
+            self._common_post_interdiff_comments(comment_text)
+
+        review_request = ReviewRequest.objects.get(pk=review_request_id)
+        review = Review.objects.get(pk=review_id)
+
+        rsp = self.apiGet(self.get_list_url(review), {
+            'interdiff-revision': interdiff_revision,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('diff_comments' in rsp)
+        self.assertEqual(len(rsp['diff_comments']), 1)
+        self.assertEqual(rsp['diff_comments'][0]['text'], comment_text)
+
+    def test_delete_diff_comment_with_interdiff(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/diff-comments/<id>/ API"""
+        comment_text = "This is a test comment."
+
+        rsp, review_request_id, review_id, interdiff_revision = \
+            self._common_post_interdiff_comments(comment_text)
+
+        rsp = self.apiDelete(rsp['diff_comment']['links']['self']['href'])
+
+        review_request = ReviewRequest.objects.get(pk=review_request_id)
+        review = Review.objects.get(pk=review_id)
+
+        rsp = self.apiGet(self.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('diff_comments' in rsp)
+        self.assertEqual(len(rsp['diff_comments']), 0)
+
+    def test_delete_diff_comment_with_site(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/diff-comments/<id>/ API with a local site"""
+        review_id = self.test_post_diff_comments_with_site()
+        review = Review.objects.get(pk=review_id)
+        review_request = review.review_request
+        comment = review.comments.all()[0]
+        comment_count = review.comments.count()
+
+        self.apiDelete(self.get_item_url(review, comment.id,
+                                         self.local_site_name))
+
+        self.assertEqual(review.comments.count(), comment_count - 1)
+
+    def test_delete_diff_comment_with_site_no_access(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/diff-comments/<id>/ API with a local site and Permission Denied error"""
+        review_id = self.test_post_diff_comments_with_site()
+        review = Review.objects.get(pk=review_id)
+        review_request = review.review_request
+        comment = review.comments.all()[0]
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiDelete(
+            self.get_item_url(review, comment.id, self.local_site_name),
+            expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def _common_post_interdiff_comments(self, comment_text):
+        # Post the review request
+        rsp = self._postNewReviewRequest()
+        review_request = ReviewRequest.objects.get(
+            pk=rsp['review_request']['id'])
+
+        # Post the diff.
+        rsp = self._postNewDiff(review_request)
+        review_request.publish(self.user)
+        diffset = DiffSet.objects.get(pk=rsp['diff']['id'])
+        filediff = diffset.files.all()[0]
+
+        # Post the second diff.
+        rsp = self._postNewDiff(review_request)
+        review_request.publish(self.user)
+        interdiffset = DiffSet.objects.get(pk=rsp['diff']['id'])
+        interfilediff = interdiffset.files.all()[0]
+
+        rsp = self.apiPost(ReviewResourceTests.get_list_url(review_request))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+
+        rsp = self._postNewDiffComment(review_request, review_id,
+                                       comment_text,
+                                       filediff_id=filediff.id,
+                                       interfilediff_id=interfilediff.id)
+
+        return rsp, review_request.id, review_id, interdiffset.revision
+
+    @classmethod
+    def get_list_url(cls, review, local_site_name=None):
+        return local_site_reverse(
+            'diff-comments-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+            })
+
+    def get_item_url(self, review, comment_id, local_site_name=None):
+        return local_site_reverse(
+            'diff-comment-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+                'comment_id': comment_id,
+            })
+
+
+class DraftReviewScreenshotCommentResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewScreenshotCommentResource APIs."""
+    def test_get_review_screenshot_comments(self):
+        """Testing the GET review-requests/<id>/reviews/draft/screenshot-comments/ API"""
+        screenshot_comment_text = "Test screenshot comment"
+        x, y, w, h = 2, 2, 10, 10
+
+        # Post the review request
+        rsp = self._postNewReviewRequest()
+        review_request = ReviewRequest.objects.get(
+            pk=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(self.user)
+
+        rsp = self.apiPost(ReviewResourceTests.get_list_url(review_request))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+        review = Review.objects.get(pk=review_id)
+
+        self._postNewScreenshotComment(review_request, review_id, screenshot,
+                                       screenshot_comment_text, x, y, w, h)
+
+        rsp = self.apiGet(self.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('screenshot_comments' in rsp)
+        self.assertEqual(len(rsp['screenshot_comments']), 1)
+        self.assertEqual(rsp['screenshot_comments'][0]['text'],
+                         screenshot_comment_text)
+
+    def test_get_review_screenshot_comments_with_site(self):
+        """Testing the GET review-requests/<id>/reviews/draft/screenshot-comments/ APIs with a local site"""
+        screenshot_comment_text = "Test screenshot comment"
+        x, y, w, h = 2, 2, 10, 10
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+        review_request.publish(User.objects.get(username='doc'))
+
+        rsp = self.apiPost(
+            ReviewResourceTests.get_list_url(review_request,
+                                             self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+        review = Review.objects.get(pk=review_id)
+
+        self._postNewScreenshotComment(review_request, review_id, screenshot,
+                                       screenshot_comment_text, x, y, w, h)
+
+        rsp = self.apiGet(self.get_list_url(review, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('screenshot_comments' in rsp)
+        self.assertEqual(len(rsp['screenshot_comments']), 1)
+        self.assertEqual(rsp['screenshot_comments'][0]['text'],
+                         screenshot_comment_text)
+
+    @classmethod
+    def get_list_url(self, review, local_site_name=None):
+        return local_site_reverse(
+            'screenshot-comments-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+            })
+
+    def get_item_url(self, review, comment_id, local_site_name=None):
+        return local_site_reverse(
+            'screenshot-comment-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+                'comment_id': comment_id,
+            })
+
+
+class ReviewReplyResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewReplyResource APIs."""
+    def test_get_replies(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/replies API"""
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+        self.test_put_reply()
+
+        public_replies = review.public_replies()
+
+        rsp = self.apiGet(self.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['replies']), public_replies.count())
+
+        for i in range(public_replies.count()):
+            reply = public_replies[i]
+            self.assertEqual(rsp['replies'][i]['id'], reply.id)
+            self.assertEqual(rsp['replies'][i]['body_top'], reply.body_top)
+            self.assertEqual(rsp['replies'][i]['body_bottom'],
+                             reply.body_bottom)
+
+    def test_get_replies_with_counts_only(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/replies/?counts-only=1 API"""
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+        self.test_put_reply()
+
+        rsp = self.apiGet('%s?counts-only=1' % self.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['count'], review.public_replies().count())
+
+    def test_get_replies_with_site(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/replies/ API with a local site"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        reply = Review()
+        reply.review_request = review_request
+        reply.user = review.user
+        reply.public = True
+        reply.base_reply_to = review
+        reply.save()
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        public_replies = review.public_replies()
+
+        rsp = self.apiGet(self.get_list_url(review, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(rsp['replies']), public_replies.count())
+
+        for i in range(public_replies.count()):
+            reply = public_replies[i]
+            self.assertEqual(rsp['replies'][i]['id'], reply.id)
+            self.assertEqual(rsp['replies'][i]['body_top'], reply.body_top)
+            self.assertEqual(rsp['replies'][i]['body_bottom'],
+                             reply.body_bottom)
+
+    def test_get_replies_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/reviews/<id>/replies/ API with a local site and Permission Denied error"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        rsp = self.apiGet(self.get_list_url(review, self.local_site_name),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_post_replies(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/ API"""
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+
+        rsp = self.apiPost(self.get_list_url(review), {
+            'body_top': 'Test',
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        self.assertEqual(len(mail.outbox), 0)
+
+    def test_post_replies_with_site(self):
+        """Testing the POST review-requsets/<id>/reviews/<id>/replies/ API with a local site"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiPost(self.get_list_url(review, self.local_site_name),
+                           { 'body_top': 'Test', })
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(len(mail.outbox), 0)
+
+    def test_post_replies_with_site_no_access(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/ API with a local site and Permission Denied error"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        rsp = self.apiPost(self.get_list_url(review, self.local_site_name),
+                           { 'body_top': 'Test', },
+                           expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_post_replies_with_body_top(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/ API with body_top"""
+        body_top = 'My Body Top'
+
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+
+        rsp = self.apiPost(self.get_list_url(review), {
+            'body_top': body_top,
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply = Review.objects.get(pk=rsp['reply']['id'])
+        self.assertEqual(reply.body_top, body_top)
+
+    def test_post_replies_with_body_bottom(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/ API with body_bottom"""
+        body_bottom = 'My Body Bottom'
+
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+
+        rsp = self.apiPost(self.get_list_url(review), {
+            'body_bottom': body_bottom,
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply = Review.objects.get(pk=rsp['reply']['id'])
+        self.assertEqual(reply.body_bottom, body_bottom)
+
+    def test_put_reply(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/replies/<id>/ API"""
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+
+        rsp, response = self.api_post_with_response(self.get_list_url(review))
+
+        self.assertTrue('Location' in response)
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+
+        rsp = self.apiPut(response['Location'], {
+            'body_top': 'Test',
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+    def test_put_reply_with_site(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/replies/<id>/ API with a local site"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp, response = self.api_post_with_response(
+            self.get_list_url(review, self.local_site_name))
+        self.assertTrue('Location' in response)
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+
+        rsp = self.apiPut(response['Location'],
+                          { 'body_top': 'Test', })
+        self.assertEqual(rsp['stat'], 'ok')
+
+    def test_put_reply_with_site_no_access(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/replies/<id>/ API with a local site and Permission Denied error"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        reply = Review()
+        reply.review_request = review_request
+        reply.user = review.user
+        reply.public = True
+        reply.base_reply_to = review
+        reply.save()
+
+        rsp = self.apiPut(self.get_item_url(review, reply.id,
+                                            self.local_site_name),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_put_reply_publish(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/replies/<id>/?public=1 API"""
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+
+        rsp, response = self.api_post_with_response(self.get_list_url(review))
+
+        self.assertTrue('Location' in response)
+        self.assertTrue('stat' in rsp)
+        self.assertEqual(rsp['stat'], 'ok')
+
+        rsp = self.apiPut(response['Location'], {
+            'body_top': 'Test',
+            'public': True,
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply = Review.objects.get(pk=rsp['reply']['id'])
+        self.assertEqual(reply.public, True)
+
+        self.assertEqual(len(mail.outbox), 1)
+
+    def test_delete_reply(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/replies/<id>/ API"""
+        review = \
+            Review.objects.filter(base_reply_to__isnull=True, public=True)[0]
+
+        rsp = self.apiPost(self.get_list_url(review), {
+            'body_top': 'Test',
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply_id = rsp['reply']['id']
+        rsp = self.apiDelete(rsp['reply']['links']['self']['href'])
+
+        self.assertEqual(Review.objects.filter(pk=reply_id).count(), 0)
+
+    def test_delete_reply_with_site(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/replies/<id>/ API with a local site"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        reply = Review()
+        reply.review_request = review_request
+        reply.user = review.user
+        reply.public = False
+        reply.base_reply_to = review
+        reply.save()
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        self.apiDelete(self.get_item_url(review, reply.id,
+                                         self.local_site_name))
+        self.assertEqual(review.replies.count(), 0)
+
+    def test_delete_reply_with_site_no_access(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/replies/<id>/ API with a local site and Permission Denied error"""
+        review_request = \
+            ReviewRequest.objects.filter(local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.public = True
+        review.save()
+
+        reply = Review()
+        reply.review_request = review_request
+        reply.user = review.user
+        reply.public = False
+        reply.base_reply_to = review
+        reply.save()
+
+        rsp = self.apiDelete(self.get_item_url(review, reply.id,
+                                               self.local_site_name),
+                             expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    @classmethod
+    def get_list_url(cls, review, local_site_name=None):
+        return local_site_reverse(
+            'replies-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+            })
+
+    def get_item_url(self, review, reply_id, local_site_name=None):
+        return local_site_reverse(
+            'reply-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+                'reply_id': reply_id,
+            })
+
+
+class ReviewReplyDiffCommentResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewReplyDiffCommentResource APIs."""
+    def test_post_reply_with_diff_comment(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/<id>/diff-comments/ API"""
+        comment_text = "My Comment Text"
+
+        comment = Comment.objects.all()[0]
+        review = comment.review.get()
+
+        # Create the reply
+        rsp = self.apiPost(ReviewReplyResourceTests.get_list_url(review))
+        self.assertEqual(rsp['stat'], 'ok')
+
+        self.assertTrue('reply' in rsp)
+        self.assertNotEqual(rsp['reply'], None)
+        self.assertTrue('links' in rsp['reply'])
+        self.assertTrue('diff_comments' in rsp['reply']['links'])
+
+        rsp = self.apiPost(rsp['reply']['links']['diff_comments']['href'], {
+            'reply_to_id': comment.id,
+            'text': comment_text,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply_comment = Comment.objects.get(pk=rsp['diff_comment']['id'])
+        self.assertEqual(reply_comment.text, comment_text)
+
+        return rsp
+
+    def test_post_reply_with_diff_comment_and_local_site(self, badlogin=False):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/<id>/diff-comments/ API with a local site"""
+        comment_text = 'My Comment Text'
+
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        review = Review()
+        review.review_request = review_request
+        review.user = User.objects.get(username='doc')
+        review.save()
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self._postNewDiffComment(review_request, review.id, 'Comment')
+        review = Review.objects.get(pk=review.id)
+        review.public = True
+        review.save()
+
+        self.assertTrue('diff_comment' in rsp)
+        self.assertTrue('id' in rsp['diff_comment'])
+        comment_id = rsp['diff_comment']['id']
+
+        rsp = self.apiPost(
+            ReviewReplyResourceTests.get_list_url(review, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+
+        self.assertTrue('reply' in rsp)
+        self.assertNotEqual(rsp['reply'], None)
+        self.assertTrue('links' in rsp['reply'])
+        self.assertTrue('diff_comments' in rsp['reply']['links'])
+
+        post_data = {
+            'reply_to_id': comment_id,
+            'text': comment_text,
+        }
+
+        if badlogin:
+            self.client.logout()
+            self.client.login(username='grumpy', password='grumpy')
+            rsp = self.apiPost(rsp['reply']['links']['diff_comments']['href'],
+                               post_data,
+                               expected_status=403)
+            self.assertEqual(rsp['stat'], 'fail')
+            self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+        else:
+            rsp = self.apiPost(rsp['reply']['links']['diff_comments']['href'],
+                               post_data)
+            self.assertEqual(rsp['stat'], 'ok')
+
+            reply_comment = Comment.objects.get(pk=rsp['diff_comment']['id'])
+            self.assertEqual(reply_comment.text, comment_text)
+
+            return rsp
+
+    def test_post_reply_with_diff_comment_and_local_site_no_access(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/<id>/diff-comments/ API with a local site and Permission Denied error"""
+        self.test_post_reply_with_diff_comment_and_local_site(True)
+
+    def test_put_reply_with_diff_comment(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/replies/<id>/diff-comments/ API"""
+        new_comment_text = 'My new comment text'
+
+        # First, create a comment that we can update.
+        rsp = self.test_post_reply_with_diff_comment()
+
+        reply_comment = Comment.objects.get(pk=rsp['diff_comment']['id'])
+
+        rsp = self.apiPut(rsp['diff_comment']['links']['self']['href'], {
+            'text': new_comment_text,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply_comment = Comment.objects.get(pk=rsp['diff_comment']['id'])
+        self.assertEqual(reply_comment.text, new_comment_text)
+
+    def test_put_reply_with_diff_comment_and_local_site(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/replies/<id>/diff-comments/ API with a local site"""
+        new_comment_text = 'My new comment text'
+
+        rsp = self.test_post_reply_with_diff_comment_and_local_site()
+
+        reply_comment = Comment.objects.get(pk=rsp['diff_comment']['id'])
+
+        rsp = self.apiPut(rsp['diff_comment']['links']['self']['href'],
+                          { 'text': new_comment_text, })
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply_comment = Comment.objects.get(pk=rsp['diff_comment']['id'])
+        self.assertEqual(reply_comment.text, new_comment_text)
+
+    def test_put_reply_with_diff_comment_and_local_site_no_access(self):
+        """Testing the PUT review-requests/<id>/reviews/<id>/replies/<id>/diff-comments/ API with a local site and Permission Denied error"""
+        new_comment_text = 'My new comment text'
+
+        rsp = self.test_post_reply_with_diff_comment_and_local_site()
+
+        reply_comment = Comment.objects.get(pk=rsp['diff_comment']['id'])
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiPut(rsp['diff_comment']['links']['self']['href'],
+                          { 'text': new_comment_text, },
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+
+class ReviewReplyScreenshotCommentResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewReplyScreenshotCommentResource APIs."""
+    def test_post_reply_with_screenshot_comment(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/<id>/screenshot-comments/ API"""
+        comment_text = "My Comment Text"
+        x, y, w, h = 10, 10, 20, 20
+
+        rsp = self._postNewReviewRequest()
+        review_request = \
+            ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+        replies_url = rsp['review']['links']['replies']['href']
+
+        rsp = self._postNewScreenshotComment(review_request, review.id,
+                                             screenshot, comment_text,
+                                             x, y, w, h)
+
+        self.assertTrue('screenshot_comment' in rsp)
+        self.assertEqual(rsp['screenshot_comment']['text'], comment_text)
+        self.assertEqual(rsp['screenshot_comment']['x'], x)
+        self.assertEqual(rsp['screenshot_comment']['y'], y)
+        self.assertEqual(rsp['screenshot_comment']['w'], w)
+        self.assertEqual(rsp['screenshot_comment']['h'], h)
+
+        comment = ScreenshotComment.objects.get(
+            pk=rsp['screenshot_comment']['id'])
+
+        rsp = self.apiPost(replies_url)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('reply' in rsp)
+        self.assertNotEqual(rsp['reply'], None)
+        self.assertTrue('links' in rsp['reply'])
+        self.assertTrue('screenshot_comments' in rsp['reply']['links'])
+
+        screenshot_comments_url = \
+            rsp['reply']['links']['screenshot_comments']['href']
+
+        rsp = self.apiPost(screenshot_comments_url, {
+            'reply_to_id': comment.id,
+            'text': comment_text,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply_comment = ScreenshotComment.objects.get(
+            pk=rsp['screenshot_comment']['id'])
+        self.assertEqual(reply_comment.text, comment_text)
+        self.assertEqual(reply_comment.reply_to, comment)
+
+    def test_post_reply_with_screenshot_comment_and_local_site(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/replies/<id>/screenshot-comments/ API with a local site"""
+        comment_text = "My Comment Text"
+        x, y, w, h = 10, 10, 20, 20
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+        replies_url = rsp['review']['links']['replies']['href']
+
+        rsp = self._postNewScreenshotComment(review_request, review.id,
+                                             screenshot, comment_text,
+                                             x, y, w, h)
+
+        self.assertTrue('screenshot_comment' in rsp)
+        self.assertEqual(rsp['screenshot_comment']['text'], comment_text)
+        self.assertEqual(rsp['screenshot_comment']['x'], x)
+        self.assertEqual(rsp['screenshot_comment']['y'], y)
+        self.assertEqual(rsp['screenshot_comment']['w'], w)
+        self.assertEqual(rsp['screenshot_comment']['h'], h)
+
+        comment = ScreenshotComment.objects.get(
+            pk=rsp['screenshot_comment']['id'])
+
+        rsp = self.apiPost(replies_url)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('reply' in rsp)
+        self.assertNotEqual(rsp['reply'], None)
+        self.assertTrue('links' in rsp['reply'])
+        self.assertTrue('screenshot_comments' in rsp['reply']['links'])
+
+        screenshot_comments_url = \
+            rsp['reply']['links']['screenshot_comments']['href']
+
+        post_data = {
+            'reply_to_id': comment.id,
+            'text': comment_text,
+        }
+
+        rsp = self.apiPost(screenshot_comments_url, post_data)
+        self.assertEqual(rsp['stat'], 'ok')
+
+        reply_comment = ScreenshotComment.objects.get(
+            pk=rsp['screenshot_comment']['id'])
+        self.assertEqual(reply_comment.text, comment_text)
+
+
+class DiffResourceTests(BaseWebAPITestCase):
+    """Testing the DiffResource APIs."""
+
+    def test_post_diffs(self):
+        """Testing the POST review-requests/<id>/diffs/ API"""
+        rsp = self._postNewReviewRequest()
+        self.assertEqual(rsp['stat'], 'ok')
+        ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+        diff_filename = os.path.join(
+            os.path.dirname(os.path.dirname(__file__)),
+            "scmtools", "testdata", "svn_makefile.diff")
+        f = open(diff_filename, "r")
+        rsp = self.apiPost(rsp['review_request']['links']['diffs']['href'], {
+            'path': f,
+            'basedir': "/trunk",
+        })
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+    def test_post_diffs_with_missing_data(self):
+        """Testing the POST review-requests/<id>/diffs/ API with Invalid Form Data"""
+        rsp = self._postNewReviewRequest()
+        self.assertEqual(rsp['stat'], 'ok')
+        ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+        rsp = self.apiPost(rsp['review_request']['links']['diffs']['href'],
+                           expected_status=400)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], INVALID_FORM_DATA.code)
+        self.assert_('path' in rsp['fields'])
+
+        # Now test with a valid path and an invalid basedir.
+        # This is necessary because basedir is "optional" as defined by
+        # the resource, but may be required by the form that processes the
+        # diff.
+        rsp = self._postNewReviewRequest()
+        self.assertEqual(rsp['stat'], 'ok')
+        ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+        diff_filename = os.path.join(
+            os.path.dirname(os.path.dirname(__file__)),
+            "scmtools", "testdata", "svn_makefile.diff")
+        f = open(diff_filename, "r")
+        rsp = self.apiPost(rsp['review_request']['links']['diffs']['href'], {
+            'path': f,
+        }, expected_status=400)
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], INVALID_FORM_DATA.code)
+        self.assert_('basedir' in rsp['fields'])
+
+    def test_post_diffs_with_site(self):
+        """Testing the POST review-requests/<id>/diffs/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_id=rsp['review_request']['id'],
+            local_site__name=self.local_site_name)
+
+        diff_filename = os.path.join(
+            os.path.dirname(os.path.dirname(__file__)),
+            'scmtools', 'testdata', 'git_deleted_file_indication.diff')
+        f = open(diff_filename, 'r')
+        rsp = self.apiPost(rsp['review_request']['links']['diffs']['href'],
+                           { 'path': f, })
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['diff']['name'],
+                         'git_deleted_file_indication.diff')
+
+
+    def test_get_diffs(self):
+        """Testing the GET review-requests/<id>/diffs/ API"""
+        review_request = ReviewRequest.objects.get(pk=2)
+        rsp = self.apiGet(self.get_list_url(review_request))
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['diffs'][0]['id'], 2)
+        self.assertEqual(rsp['diffs'][0]['name'], 'cleaned_data.diff')
+
+    def test_get_diffs_with_site(self):
+        """Testing the GET review-requests/<id>/diffs API with a local site"""
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiGet(self.get_list_url(review_request,
+                                            self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['diffs'][0]['id'],
+                         review_request.diffset_history.diffsets.latest().id)
+        self.assertEqual(rsp['diffs'][0]['name'],
+                         review_request.diffset_history.diffsets.latest().name)
+
+    def test_get_diffs_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/diffs API with a local site and Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+        self.apiGet(self.get_list_url(review_request, self.local_site_name),
+                    expected_status=403)
+
+    def test_get_diff(self):
+        """Testing the GET review-requests/<id>/diffs/<revision>/ API"""
+        review_request = ReviewRequest.objects.get(pk=2)
+        rsp = self.apiGet(self.get_item_url(review_request, 1))
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['diff']['id'], 2)
+        self.assertEqual(rsp['diff']['name'], 'cleaned_data.diff')
+
+    def test_get_diff_with_site(self):
+        """Testing the GET review-requests/<id>/diffs/<revision>/ API with a local site"""
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+        diff = review_request.diffset_history.diffsets.latest()
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        rsp = self.apiGet(self.get_item_url(review_request, diff.revision,
+                                            self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['diff']['id'], diff.id)
+        self.assertEqual(rsp['diff']['name'], diff.name)
+
+    def test_get_diff_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/diffs/<revision>/ API with a local site and Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+        diff = review_request.diffset_history.diffsets.latest()
+        self.apiGet(self.get_item_url(review_request, diff.revision,
+                                      self.local_site_name),
+                    expected_status=403)
+
+    @classmethod
+    def get_list_url(cls, review_request, local_site_name=None):
+        return local_site_reverse(
+            'diffs-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+            })
+
+    def get_item_url(self, review_request, diff_revision, local_site_name=None):
+        return local_site_reverse(
+            'diff-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+                'diff_revision': diff_revision,
+            })
+
+
+class ScreenshotDraftResourceTests(BaseWebAPITestCase):
+    """Testing the ScreenshotDraftResource APIs."""
+    def test_post_screenshots(self):
+        """Testing the POST review-requests/<id>/draft/screenshots/ API"""
+        rsp = self._postNewReviewRequest()
+        self.assertEqual(rsp['stat'], 'ok')
+        ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+        screenshots_url = rsp['review_request']['links']['screenshots']['href']
+
+        f = open(self._getTrophyFilename(), "r")
+        self.assertNotEqual(f, None)
+        rsp = self.apiPost(screenshots_url, {
+            'path': f,
+        })
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+    def test_post_screenshots_with_permission_denied_error(self):
+        """Testing the POST review-requests/<id>/draft/screenshots/ API with Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(public=True,
+            local_site=None).exclude(submitter=self.user)[0]
+
+        f = open(self._getTrophyFilename(), "r")
+        self.assert_(f)
+        rsp = self.apiPost(self.get_list_url(review_request), {
+            'caption': 'Trophy',
+            'path': f,
+        }, expected_status=403)
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_post_screenshots_with_site(self):
+        """Testing the POST review-requests/<id>/draft/screenshots/ API with a local site"""
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        f = open(self._getTrophyFilename(), 'r')
+        self.assertNotEqual(f, None)
+
+        post_data = {
+            'path': f,
+            'caption': 'Trophy',
+        }
+
+        rsp = self.apiPost(self.get_list_url(review_request,
+                                             self.local_site_name),
+                           post_data)
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertEqual(rsp['draft_screenshot']['caption'], 'Trophy')
+
+        draft = review_request.get_draft(User.objects.get(username='doc'))
+        self.assertNotEqual(draft, None)
+
+        return review_request, rsp['draft_screenshot']['id']
+
+    def test_post_screenshots_with_site_no_access(self):
+        """Testing the POST review-requests/<id>/draft/screenshots/ API with a local site and Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+
+        f = open(self._getTrophyFilename(), 'r')
+        self.assertNotEqual(f, None)
+        rsp = self.apiPost(self.get_list_url(review_request,
+                                             self.local_site_name),
+                           { 'path': f, },
+                           expected_status=403)
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_put_screenshot(self):
+        """Testing the PUT review-requests/<id>/draft/screenshots/<id>/ API"""
+        draft_caption = 'The new caption'
+
+        rsp = self._postNewReviewRequest()
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = \
+            ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+        f = open(self._getTrophyFilename(), "r")
+        self.assert_(f)
+        rsp = self.apiPost(self.get_list_url(review_request), {
+            'caption': 'Trophy',
+            'path': f,
+        })
+        f.close()
+        review_request.publish(self.user)
+
+        screenshot = Screenshot.objects.get(pk=rsp['draft_screenshot']['id'])
+
+        # Now modify the caption.
+        rsp = self.apiPut(self.get_item_url(review_request, screenshot.id), {
+            'caption': draft_caption,
+        })
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+        draft = review_request.get_draft(self.user)
+        self.assertNotEqual(draft, None)
+
+        screenshot = Screenshot.objects.get(pk=screenshot.id)
+        self.assertEqual(screenshot.draft_caption, draft_caption)
+
+    def test_put_screenshot_with_site(self):
+        """Testing the PUT review-requests/<id>/draft/screenshots/<id>/ API with a local site"""
+        draft_caption = 'The new caption'
+        user = User.objects.get(username='doc')
+
+        review_request, screenshot_id = self.test_post_screenshots_with_site()
+        review_request.publish(user)
+
+        rsp = self.apiPut(self.get_item_url(review_request, screenshot_id,
+                                            self.local_site_name),
+                          { 'caption': draft_caption, })
+        self.assertEqual(rsp['stat'], 'ok')
+
+        draft = review_request.get_draft(user)
+        self.assertNotEqual(draft, None)
+
+        screenshot = Screenshot.objects.get(pk=screenshot_id)
+        self.assertEqual(screenshot.draft_caption, draft_caption)
+
+    def test_put_screenshot_with_site_no_access(self):
+        """Testing the PUT review-requests/<id>/draft/screenshots/<id>/ API with a local site and Permission Denied error"""
+        review_request, screenshot_id = self.test_post_screenshots_with_site()
+        review_request.publish(User.objects.get(username='doc'))
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiPut(self.get_item_url(review_request, screenshot_id,
+                                            self.local_site_name),
+                          { 'caption': 'test', },
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def get_list_url(self, review_request, local_site_name=None):
+        return local_site_reverse(
+            'draft-screenshots-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+            })
+
+    def get_item_url(self, review_request, screenshot_id, local_site_name=None):
+        return local_site_reverse(
+            'draft-screenshot-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+                'screenshot_id': screenshot_id,
+            })
+
+
+class ScreenshotResourceTests(BaseWebAPITestCase):
+    """Testing the ScreenshotResource APIs."""
+    def test_post_screenshots(self):
+        """Testing the POST review-requests/<id>/screenshots/ API"""
+        rsp = self._postNewReviewRequest()
+        self.assertEqual(rsp['stat'], 'ok')
+        ReviewRequest.objects.get(pk=rsp['review_request']['id'])
+
+        screenshots_url = rsp['review_request']['links']['screenshots']['href']
+
+        f = open(self._getTrophyFilename(), "r")
+        self.assertNotEqual(f, None)
+        rsp = self.apiPost(screenshots_url, {
+            'path': f,
+        })
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+    def test_post_screenshots_with_permission_denied_error(self):
+        """Testing the POST review-requests/<id>/screenshots/ API with Permission Denied error"""
+        review_request = ReviewRequest.objects.filter(public=True,
+            local_site=None).exclude(submitter=self.user)[0]
+
+        f = open(self._getTrophyFilename(), "r")
+        self.assert_(f)
+        rsp = self.apiPost(self.get_list_url(review_request), {
+            'caption': 'Trophy',
+            'path': f,
+        }, expected_status=403)
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def _test_review_request_with_site(self):
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        return rsp['review_request']['links']['screenshots']['href']
+
+    def test_post_screenshots_with_site(self):
+        """Testing the POST review-requests/<id>/screenshots/ API with a local site"""
+        screenshots_url = self._test_review_request_with_site()
+
+        f = open(self._getTrophyFilename(), 'r')
+        self.assertNotEqual(f, None)
+        rsp = self.apiPost(screenshots_url, { 'path': f, })
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'ok')
+
+    def test_post_screenshots_with_site_no_access(self):
+        """Testing the POST review-requests/<id>/screenshots/ API with a local site and Permission Denied error"""
+        screenshots_url = self._test_review_request_with_site()
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        f = open(self._getTrophyFilename(), 'r')
+        self.assertNotEqual(f, None)
+        rsp = self.apiPost(screenshots_url,
+                           { 'path': f, },
+                           expected_status=403)
+        f.close()
+
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    @classmethod
+    def get_list_url(cls, review_request, local_site_name=None):
+        return local_site_reverse(
+            'screenshots-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+            })
+
+
+class FileDiffCommentResourceTests(BaseWebAPITestCase):
+    """Testing the FileDiffCommentResource APIs."""
+    def test_get_comments(self):
+        """Testing the GET review-requests/<id>/diffs/<revision>/files/<id>/diff-comments/ API"""
+        diff_comment_text = 'Sample comment.'
+
+        review_request = ReviewRequest.objects.public()[0]
+        diffset = review_request.diffset_history.diffsets.latest()
+        filediff = diffset.files.all()[0]
+
+        rsp = self.apiPost(ReviewResourceTests.get_list_url(review_request))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+
+        self._postNewDiffComment(review_request, review_id, diff_comment_text)
+
+        rsp = self.apiGet(self.get_list_url(filediff))
+        self.assertEqual(rsp['stat'], 'ok')
+
+        comments = Comment.objects.filter(filediff=filediff)
+        self.assertEqual(len(rsp['diff_comments']), comments.count())
+
+        for i in range(0, len(rsp['diff_comments'])):
+            self.assertEqual(rsp['diff_comments'][i]['text'], comments[i].text)
+
+    def test_get_comments_with_site(self):
+        """Testing the GET review-requests/<id>/diffs/<revision>/files/<id>/diff-comments/ API with a local site"""
+        diff_comment_text = 'Sample comment.'
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+        diffset = review_request.diffset_history.diffsets.latest()
+        filediff = diffset.files.all()[0]
+
+        rsp = self.apiPost(
+            ReviewResourceTests.get_list_url(review_request,
+                                             self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+
+        self._postNewDiffComment(review_request, review_id, diff_comment_text)
+
+        rsp = self.apiGet(self.get_list_url(filediff, self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+
+        comments = Comment.objects.filter(filediff=filediff)
+        self.assertEqual(len(rsp['diff_comments']), comments.count())
+
+        for i in range(0, len(rsp['diff_comments'])):
+            self.assertEqual(rsp['diff_comments'][i]['text'], comments[i].text)
+
+    def test_get_comments_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/diffs/<revision>/files/<id>/diff-comments/ API with a local site and Permission Denied error"""
+        diff_comment_text = 'Sample comment.'
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        review_request = ReviewRequest.objects.filter(
+            local_site__name=self.local_site_name)[0]
+        diffset = review_request.diffset_history.diffsets.latest()
+        filediff = diffset.files.all()[0]
+
+        rsp = self.apiPost(
+            ReviewResourceTests.get_list_url(review_request,
+                                             self.local_site_name))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+
+        self._postNewDiffComment(review_request, review_id, diff_comment_text)
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiGet(self.get_list_url(filediff, self.local_site_name),
+                          expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_get_comments_with_line(self):
+        """Testing the GET review-requests/<id>/diffs/<revision>/files/<id>/diff-comments/?line= API"""
+        diff_comment_text = 'Sample comment.'
+        diff_comment_line = 10
+
+        review_request = ReviewRequest.objects.public()[0]
+        diffset = review_request.diffset_history.diffsets.latest()
+        filediff = diffset.files.all()[0]
+
+        rsp = self.apiPost(ReviewResourceTests.get_list_url(review_request))
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('review' in rsp)
+        review_id = rsp['review']['id']
+
+        self._postNewDiffComment(review_request, review_id, diff_comment_text,
+                                 first_line=diff_comment_line)
+
+        self._postNewDiffComment(review_request, review_id, diff_comment_text,
+                                 first_line=diff_comment_line + 1)
+
+        rsp = self.apiGet(self.get_list_url(filediff), {
+            'line': diff_comment_line,
+        })
+        self.assertEqual(rsp['stat'], 'ok')
+
+        comments = Comment.objects.filter(filediff=filediff,
+                                          first_line=diff_comment_line)
+        self.assertEqual(len(rsp['diff_comments']), comments.count())
+
+        for i in range(0, len(rsp['diff_comments'])):
+            self.assertEqual(rsp['diff_comments'][i]['text'], comments[i].text)
+            self.assertEqual(rsp['diff_comments'][i]['first_line'],
+                             comments[i].first_line)
+
+    def get_list_url(self, filediff, local_site_name=None):
+        diffset = filediff.diffset
+        review_request = diffset.history.review_request.get()
+
+        return local_site_reverse(
+            'diff-comments-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review_request.display_id,
+                'diff_revision': filediff.diffset.revision,
+                'filediff_id': filediff.pk,
+            })
+
+
+class ScreenshotCommentResourceTests(BaseWebAPITestCase):
+    """Testing the ScreenshotCommentResource APIs."""
+    def test_get_screenshot_comments(self):
+        """Testing the GET review-requests/<id>/screenshots/<id>/comments/ API"""
+        comment_text = "This is a test comment."
+        x, y, w, h = (2, 2, 10, 10)
+
+        # Post the review request
+        rsp = self._postNewReviewRequest()
+        review_request = ReviewRequest.objects.get(
+            pk=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+        self.assertTrue('links' in rsp['screenshot'])
+        self.assertTrue('screenshot_comments' in rsp['screenshot']['links'])
+        comments_url = rsp['screenshot']['links']['screenshot_comments']['href']
+
+        # Make these public.
+        review_request.publish(self.user)
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        self._postNewScreenshotComment(review_request, review.id, screenshot,
+                                      comment_text, x, y, w, h)
+
+        rsp = self.apiGet(comments_url)
+        self.assertEqual(rsp['stat'], 'ok')
+
+        comments = ScreenshotComment.objects.filter(screenshot=screenshot)
+        rsp_comments = rsp['screenshot_comments']
+        self.assertEqual(len(rsp_comments), comments.count())
+
+        for i in range(0, len(comments)):
+            self.assertEqual(rsp_comments[i]['text'], comments[i].text)
+            self.assertEqual(rsp_comments[i]['x'], comments[i].x)
+            self.assertEqual(rsp_comments[i]['y'], comments[i].y)
+            self.assertEqual(rsp_comments[i]['w'], comments[i].w)
+            self.assertEqual(rsp_comments[i]['h'], comments[i].h)
+
+    def test_get_screenshot_comments_with_site(self):
+        """Testing the GET review-requests/<id>/screenshots/<id>/comments/ API with a local site"""
+        comment_text = 'This is a test comment.'
+        x, y, w, h = (2, 2, 10, 10)
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        # Post the review request.
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+        self.assertTrue('links' in rsp['screenshot'])
+        self.assertTrue('screenshot_comments' in rsp['screenshot']['links'])
+        comments_url = rsp['screenshot']['links']['screenshot_comments']['href']
+
+        # Make these public.
+        review_request.publish(User.objects.get(username='doc'))
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        self._postNewScreenshotComment(review_request, review.id, screenshot,
+                                       comment_text, x, y, w, h)
+
+        rsp = self.apiGet(comments_url)
+        self.assertEqual(rsp['stat'], 'ok')
+
+        comments = ScreenshotComment.objects.filter(screenshot=screenshot)
+        rsp_comments = rsp['screenshot_comments']
+        self.assertEqual(len(rsp_comments), comments.count())
+
+        for i in range(0, len(comments)):
+            self.assertEqual(rsp_comments[i]['text'], comments[i].text)
+            self.assertEqual(rsp_comments[i]['x'], comments[i].x)
+            self.assertEqual(rsp_comments[i]['y'], comments[i].y)
+            self.assertEqual(rsp_comments[i]['w'], comments[i].w)
+            self.assertEqual(rsp_comments[i]['h'], comments[i].h)
+
+    def test_get_screenshot_comments_with_site_no_access(self):
+        """Testing the GET review-requests/<id>/screenshots/<id>/comments/ API with a local site and Permission Denied error"""
+        comment_text = 'This is a test comment.'
+        x, y, w, h = (2, 2, 10, 10)
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        # Post the review request.
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+        self.assertTrue('links' in rsp['screenshot'])
+        self.assertTrue('screenshot_comments' in rsp['screenshot']['links'])
+        comments_url = rsp['screenshot']['links']['screenshot_comments']['href']
+
+        # Make these public.
+        review_request.publish(User.objects.get(username='doc'))
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        self._postNewScreenshotComment(review_request, review.id, screenshot,
+                                       comment_text, x, y, w, h)
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiGet(comments_url, expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+
+class ReviewScreenshotCommentResourceTests(BaseWebAPITestCase):
+    """Testing the ReviewScreenshotCommentResource APIs."""
+    def test_post_screenshot_comments(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/screenshot-comments/ API"""
+        comment_text = "This is a test comment."
+        x, y, w, h = (2, 2, 10, 10)
+
+        # Post the review request
+        rsp = self._postNewReviewRequest()
+        review_request = ReviewRequest.objects.get(
+            pk=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(self.user)
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        rsp = self._postNewScreenshotComment(review_request, review.id,
+                                             screenshot, comment_text,
+                                             x, y, w, h)
+
+        self.assertEqual(rsp['screenshot_comment']['text'], comment_text)
+        self.assertEqual(rsp['screenshot_comment']['x'], x)
+        self.assertEqual(rsp['screenshot_comment']['y'], y)
+        self.assertEqual(rsp['screenshot_comment']['w'], w)
+        self.assertEqual(rsp['screenshot_comment']['h'], h)
+
+    def test_post_screenshot_comments_with_site(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/screenshot-comments/ API with a local site"""
+        comment_text = 'This is a test comment.'
+        x, y, w, h = (2, 2, 10, 10)
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        # Post the review request
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(User.objects.get(username='doc'))
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        rsp = self._postNewScreenshotComment(review_request, review.id,
+                                             screenshot, comment_text,
+                                             x, y, w, h)
+
+        self.assertEqual(rsp['screenshot_comment']['text'], comment_text)
+        self.assertEqual(rsp['screenshot_comment']['x'], x)
+        self.assertEqual(rsp['screenshot_comment']['y'], y)
+        self.assertEqual(rsp['screenshot_comment']['w'], w)
+        self.assertEqual(rsp['screenshot_comment']['h'], h)
+
+    def test_post_screenshot_comments_with_site_no_access(self):
+        """Testing the POST review-requests/<id>/reviews/<id>/screenshot-comments/ API with a local site and Permission Denied error"""
+        comment_text = 'This is a test comment.'
+        x, y, w, h = (2, 2, 10, 10)
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        # Post the review request
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(User.objects.get(username='doc'))
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiPost(self.get_list_url(review, self.local_site_name),
+                           { 'screenshot_id': screenshot.id, },
+                           expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_delete_screenshot_comment(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/screenshot-comments/<id>/ API"""
+        comment_text = "This is a test comment."
+        x, y, w, h = (2, 2, 10, 10)
+
+        # Post the review request
+        rsp = self._postNewReviewRequest()
+        review_request = ReviewRequest.objects.get(
+            pk=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(self.user)
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+        screenshot_comments_url = \
+            rsp['review']['links']['screenshot_comments']['href']
+
+        rsp = self._postNewScreenshotComment(review_request, review.id,
+                                             screenshot, comment_text,
+                                             x, y, w, h)
+
+        self.apiDelete(rsp['screenshot_comment']['links']['self']['href'])
+
+        rsp = self.apiGet(screenshot_comments_url)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('screenshot_comments' in rsp)
+        self.assertEqual(len(rsp['screenshot_comments']), 0)
+
+    def test_delete_screenshot_comment_with_local_site(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/screenshot-comments/<id> API with a local site"""
+        comment_text = 'This is a test comment.'
+        x, y, w, h = (2, 2, 10, 10)
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        # Post the review request
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(User.objects.get(username='doc'))
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        screenshot_comments_url = \
+            rsp['review']['links']['screenshot_comments']['href']
+
+        rsp = self._postNewScreenshotComment(review_request, review.id,
+                                             screenshot, comment_text,
+                                             x, y, w, h)
+
+        self.apiDelete(rsp['screenshot_comment']['links']['self']['href'])
+
+        rsp = self.apiGet(screenshot_comments_url)
+        self.assertEqual(rsp['stat'], 'ok')
+        self.assertTrue('screenshot_comments' in rsp)
+        self.assertEqual(len(rsp['screenshot_comments']), 0)
+
+    def test_delete_screenshot_comment_with_local_site_no_access(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/screenshot-comments/<id> API with a local site and Permission Denied error"""
+        comment_text = 'This is a test comment.'
+        x, y, w, h = (2, 2, 10, 10)
+
+        self.client.logout()
+        self.client.login(username='doc', password='doc')
+
+        # Post the review request
+        repo = Repository.objects.get(name='Review Board Git')
+        rsp = self._postNewReviewRequest(local_site_name=self.local_site_name,
+                                         repository=repo)
+        self.assertEqual(rsp['stat'], 'ok')
+        review_request = ReviewRequest.objects.get(
+            local_site__name=self.local_site_name,
+            local_id=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        screenshot = Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(User.objects.get(username='doc'))
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        screenshot_comments_url = \
+            rsp['review']['links']['screenshot_comments']['href']
+
+        rsp = self._postNewScreenshotComment(review_request, review.id,
+                                             screenshot, comment_text,
+                                             x, y, w, h)
+
+        self.client.logout()
+        self.client.login(username='grumpy', password='grumpy')
+
+        rsp = self.apiDelete(rsp['screenshot_comment']['links']['self']['href'],
+                             expected_status=403)
+        self.assertEqual(rsp['stat'], 'fail')
+        self.assertEqual(rsp['err']['code'], PERMISSION_DENIED.code)
+
+    def test_delete_screenshot_comment_with_does_not_exist_error(self):
+        """Testing the DELETE review-requests/<id>/reviews/<id>/screenshot-comments/<id>/ API with Does Not Exist error"""
+        x, y, w, h = (2, 2, 10, 10)
+
+        # Post the review request
+        rsp = self._postNewReviewRequest()
+        review_request = ReviewRequest.objects.get(
+            pk=rsp['review_request']['id'])
+
+        # Post the screenshot.
+        rsp = self._postNewScreenshot(review_request)
+        Screenshot.objects.get(pk=rsp['screenshot']['id'])
+
+        # Make these public.
+        review_request.publish(self.user)
+
+        # Post the review.
+        rsp = self._postNewReview(review_request)
+        review = Review.objects.get(pk=rsp['review']['id'])
+
+        self.apiDelete(self.get_item_url(review, 123), expected_status=404)
+
+    @classmethod
+    def get_list_url(cls, review, local_site_name=None):
+        return local_site_reverse(
+            'screenshot-comments-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+            })
+
+    def get_item_url(cls, review, comment_id, local_site_name=None):
+        return local_site_reverse(
+            'screenshot-comment-resource',
+            local_site_name=local_site_name,
+            kwargs={
+                'review_request_id': review.review_request.display_id,
+                'review_id': review.pk,
+                'comment_id': comment_id,
+            })

application/vnd.reviewboard.org.diff.data+json

$ curl http://reviews.example.com/api10/1/44/ -H "Accept: application/json"
Content-Type: application/json
X-Content-Type-Options: nosniff
Last-Modified: Fri, 10 Aug 2018 22:16:22 GMT
ETag: 1c167e656806a95016e920297ff7695d6eb6aa61
Vary: Accept, Cookie
{
  "diff_data": {
    "binary": false,
    "changed_chunk_indexes": [
      0
    ],
    "chunks": [
      {
        "change": "insert",
        "collapsable": false,
        "index": 0,
        "lines": [
          [
            1,
            "",
            "",
            [],
            1,
            "import os",
            [],
            false
          ],
          [
            2,
            "",
            "",
            [],
            2,
            "",
            [],
            false
          ],
          [
            3,
            "",
            "",
            [],
            3,
            "from django.conf import settings",
            [],
            false
          ],
          [
            4,
            "",
            "",
            [],
            4,
            "from django.contrib.auth.models import User, Permission",
            [],
            false
          ],
          [
            5,
            "",
            "",
            [],
            5,
            "from django.core import mail",
            [],
            false
          ],
          [
            6,
            "",
            "",
            [],
            6,
            "from django.test import TestCase",
            [],
            false
          ],
          [
            7,
            "",
            "",
            [],
            7,
            "from django.utils import simplejson",
            [],
            false
          ],
          [
            8,
            "",
            "",
            [],
            8,
            "from djblets.siteconfig.models import SiteConfiguration",
            [],
            false
          ],
          [
            9,
            "",
            "",
            [],
            9,
            "from djblets.webapi.errors import DOES_NOT_EXIST, INVALID_ATTRIBUTE, \\",
            [],
            false
          ],
          [
            10,
            "",
            "",
            [],
            10,
            "                                  INVALID_FORM_DATA, PERMISSION_DENIED",
            [],
            false
          ],
          [
            11,
            "",
            "",
            [],
            11,
            "",
            [],
            false
          ],
          [
            12,
            "",
            "",
            [],
            12,
            "from reviewboard import initialize",
            [],
            false
          ],
          [
            13,
            "",
            "",
            [],
            13,
            "from reviewboard.diffviewer.models import DiffSet",
            [],
            false
          ],
          [
            14,
            "",
            "",
            [],
            14,
            "from reviewboard.notifications.tests import EmailTestHelper",
            [],
            false
          ],
          [
            15,
            "",
            "",
            [],
            15,
            "from reviewboard.reviews.models import Group, ReviewRequest, \\",
            [],
            false
          ],
          [
            16,
            "",
            "",
            [],
            16,
            "                                       ReviewRequestDraft, Review, \\",
            [],
            false
          ],
          [
            17,
            "",
            "",
            [],
            17,
            "                                       Comment, Screenshot, ScreenshotComment",
            [],
            false
          ],
          [
            18,
            "",
            "",
            [],
            18,
            "from reviewboard.scmtools.models import Repository, Tool",
            [],
            false
          ],
          [
            19,
            "",
            "",
            [],
            19,
            "from reviewboard.site.urlresolvers import local_site_reverse",
            [],
            false
          ],
          [
            20,
            "",
            "",
            [],
            20,
            "from reviewboard.site.models import LocalSite",
            [],
            false
          ],
          [
            21,
            "",
            "",
            [],
            21,
            "from reviewboard.webapi.errors import INVALID_REPOSITORY",
            [],
            false
          ],
          [
            22,
            "",
            "",
            [],
            22,
            "",
            [],
            false
          ],
          [
            23,
            "",
            "",
            [],
            23,
            "",
            [],
            false
          ],
          [
            24,
            "",
            "",
            [],
            24,
            "class BaseWebAPITestCase(TestCase, EmailTestHelper):",
            [],
            false
          ],
          [
            25,
            "",
            "",
            [],
            25,
            "    fixtures = [&#39;test_users&#39;, &#39;test_reviewrequests&#39;, &#39;test_scmtools&#39;,",
            [],
            false
          ],
          [
            26,
            "",
            "",
            [],
            26,
            "                &#39;test_site&#39;]",
            [],
            false
          ],
          [
            27,
            "",
            "",
            [],
            27,
            "    local_site_name = &#39;local-site-1&#39;",
            [],
            false
          ],
          [
            28,
            "",
            "",
            [],
            28,
            "",
            [],
            false
          ],
          [
            29,
            "",
            "",
            [],
            29,
            "    def setUp(self):",
            [],
            false
          ],
          [
            30,
            "",
            "",
            [],
            30,
            "        initialize()",
            [],
            false
          ],
          [
            31,
            "",
            "",
            [],
            31,
            "",
            [],
            false
          ],
          [
            32,
            "",
            "",
            [],
            32,
            "        siteconfig = SiteConfiguration.objects.get_current()",
            [],
            false
          ],
          [
            33,
            "",
            "",
            [],
            33,
            "        siteconfig.set(&quot;mail_send_review_mail&quot;, True)",
            [],
            false
          ],
          [
            34,
            "",
            "",
            [],
            34,
            "        siteconfig.set(&quot;auth_require_sitewide_login&quot;, False)",
            [],
            false
          ],
          [
            35,
            "",
            "",
            [],
            35,
            "        siteconfig.save()",
            [],
            false
          ],
          [
            36,
            "",
            "",
            [],
            36,
            "        mail.outbox = []",
            [],
            false
          ],
          [
            37,
            "",
            "",
            [],
            37,
            "",
            [],
            false
          ],
          [
            38,
            "",
            "",
            [],
            38,
            "        svn_repo_path = os.path.join(os.path.dirname(__file__),",
            [],
            false
          ],
          [
            39,
            "",
            "",
            [],
            39,
            "                                     &#39;../scmtools/testdata/svn_repo&#39;)",
            [],
            false
          ],
          [
            40,
            "",
            "",
            [],
            40,
            "        self.repository = Repository(name=&#39;Subversion SVN&#39;,",
            [],
            false
          ],
          [
            41,
            "",
            "",
            [],
            41,
            "                                     path=&#39;file://&#39; + svn_repo_path,",
            [],
            false
          ],
          [
            42,
            "",
            "",
            [],
            42,
            "                                     tool=Tool.objects.get(name=&#39;Subversion&#39;))",
            [],
            false
          ],
          [
            43,
            "",
            "",
            [],
            43,
            "        self.repository.save()",
            [],
            false
          ],
          [
            44,
            "",
            "",
            [],
            44,
            "",
            [],
            false
          ],
          [
            45,
            "",
            "",
            [],
            45,
            "        self.client.login(username=&quot;grumpy&quot;, password=&quot;grumpy&quot;)",
            [],
            false
          ],
          [
            46,
            "",
            "",
            [],
            46,
            "        self.user = User.objects.get(username=&quot;grumpy&quot;)",
            [],
            false
          ],
          [
            47,
            "",
            "",
            [],
            47,
            "",
            [],
            false
          ],
          [
            48,
            "",
            "",
            [],
            48,
            "        self.base_url = &#39;http://testserver&#39;",
            [],
            false
          ],
          [
            49,
            "",
            "",
            [],
            49,
            "",
            [],
            false
          ],
          [
            50,
            "",
            "",
            [],
            50,
            "    def tearDown(self):",
            [],
            false
          ],
          [
            51,
            "",
            "",
            [],
            51,
            "        self.client.logout()",
            [],
            false
          ],
          [
            52,
            "",
            "",
            [],
            52,
            "",
            [],
            false
          ],
          [
            53,
            "",
            "",
            [],
            53,
            "    def api_func_wrapper(self, api_func, path, query, expected_status,",
            [],
            false
          ],
          [
            54,
            "",
            "",
            [],
            54,
            "                         follow_redirects, expected_redirects):",
            [],
            false
          ],
          [
            55,
            "",
            "",
            [],
            55,
            "        response = api_func(path, query, follow=follow_redirects)",
            [],
            false
          ],
          [
            56,
            "",
            "",
            [],
            56,
            "        self.assertEqual(response.status_code, expected_status)",
            [],
            false
          ],
          [
            57,
            "",
            "",
            [],
            57,
            "",
            [],
            false
          ],
          [
            58,
            "",
            "",
            [],
            58,
            "        if expected_redirects:",
            [],
            false
          ],
          [
            59,
            "",
            "",
            [],
            59,
            "            self.assertEqual(len(response.redirect_chain),",
            [],
            false
          ],
          [
            60,
            "",
            "",
            [],
            60,
            "                             len(expected_redirects))",
            [],
            false
          ],
          [
            61,
            "",
            "",
            [],
            61,
            "",
            [],
            false
          ],
          [
            62,
            "",
            "",
            [],
            62,
            "            for redirect in expected_redirects:",
            [],
            false
          ],
          [
            63,
            "",
            "",
            [],
            63,
            "                self.assertEqual(response.redirect_chain[0][0],",
            [],
            false
          ],
          [
            64,
            "",
            "",
            [],
            64,
            "                                 self.base_url + expected_redirects[0])",
            [],
            false
          ],
          [
            65,
            "",
            "",
            [],
            65,
            "",
            [],
            false
          ],
          [
            66,
            "",
            "",
            [],
            66,
            "        return response",
            [],
            false
          ],
          [
            67,
            "",
            "",
            [],
            67,
            "",
            [],
            false
          ],
          [
            68,
            "",
            "",
            [],
            68,
            "    def apiGet(self, path, query={}, follow_redirects=False,",
            [],
            false
          ],
          [
            69,
            "",
            "",
            [],
            69,
            "               expected_status=200, expected_redirects=[]):",
            [],
            false
          ],
          [
            70,
            "",
            "",
            [],
            70,
            "        path = self._normalize_path(path)",
            [],
            false
          ],
          [
            71,
            "",
            "",
            [],
            71,
            "",
            [],
            false
          ],
          [
            72,
            "",
            "",
            [],
            72,
            "        print &#39;GETing %s&#39; % path",
            [],
            false
          ],
          [
            73,
            "",
            "",
            [],
            73,
            "        print &quot;Query data: %s&quot; % query",
            [],
            false
          ],
          [
            74,
            "",
            "",
            [],
            74,
            "",
            [],
            false
          ],
          [
            75,
            "",
            "",
            [],
            75,
            "        response = self.api_func_wrapper(self.client.get, path, query,",
            [],
            false
          ],
          [
            76,
            "",
            "",
            [],
            76,
            "                                         expected_status, follow_redirects,",
            [],
            false
          ],
          [
            77,
            "",
            "",
            [],
            77,
            "                                         expected_redirects)",
            [],
            false
          ],
          [
            78,
            "",
            "",
            [],
            78,
            "",
            [],
            false
          ],
          [
            79,
            "",
            "",
            [],
            79,
            "        print &quot;Raw response: %s&quot; % response.content",
            [],
            false
          ],
          [
            80,
            "",
            "",
            [],
            80,
            "",
            [],
            false
          ],
          [
            81,
            "",
            "",
            [],
            81,
            "        rsp = simplejson.loads(response.content)",
            [],
            false
          ],
          [
            82,
            "",
            "",
            [],
            82,
            "        print &quot;Response: %s&quot; % rsp",
            [],
            false
          ],
          [
            83,
            "",
            "",
            [],
            83,
            "",
            [],
            false
          ],
          [
            84,
            "",
            "",
            [],
            84,
            "        return rsp",
            [],
            false
          ],
          [
            85,
            "",
            "",
            [],
            85,
            "",
            [],
            false
          ],
          [
            86,
            "",
            "",
            [],
            86,
            "    def api_post_with_response(self, path, query={}, expected_status=201):",
            [],
            false
          ],
          [
            87,
            "",
            "",
            [],
            87,
            "        path = self._normalize_path(path)",
            [],
            false
          ],
          [
            88,
            "",
            "",
            [],
            88,
            "",
            [],
            false
          ],
          [
            89,
            "",
            "",
            [],
            89,
            "        print &#39;POSTing to %s&#39; % path",
            [],
            false
          ],
          [
            90,
            "",
            "",
            [],
            90,
            "        print &quot;Post data: %s&quot; % query",
            [],
            false
          ],
          [
            91,
            "",
            "",
            [],
            91,
            "        response = self.client.post(path, query)",
            [],
            false
          ],
          [
            92,
            "",
            "",
            [],
            92,
            "        print &quot;Raw response: %s&quot; % response.content",
            [],
            false
          ],
          [
            93,
            "",
            "",
            [],
            93,
            "        self.assertEqual(response.status_code, expected_status)",
            [],
            false
          ],
          [
            94,
            "",
            "",
            [],
            94,
            "",
            [],
            false
          ],
          [
            95,
            "",
            "",
            [],
            95,
            "        return self._get_result(response, expected_status), response",
            [],
            false
          ],
          [
            96,
            "",
            "",
            [],
            96,
            "",
            [],
            false
          ],
          [
            97,
            "",
            "",
            [],
            97,
            "    def apiPost(self, *args, **kwargs):",
            [],
            false
          ],
          [
            98,
            "",
            "",
            [],
            98,
            "        rsp, result = self.api_post_with_response(*args, **kwargs)",
            [],
            false
          ],
          [
            99,
            "",
            "",
            [],
            99,
            "",
            [],
            false
          ],
          [
            100,
            "",
            "",
            [],
            100,
            "        return rsp",
            [],
            false
          ],
          [
            101,
            "",
            "",
            [],
            101,
            "",
            [],
            false
          ],
          [
            102,
            "",
            "",
            [],
            102,
            "    def apiPut(self, path, query={}, expected_status=200,",
            [],
            false
          ],
          [
            103,
            "",
            "",
            [],
            103,
            "               follow_redirects=False, expected_redirects=[]):",
            [],
            false
          ],
          [
            104,
            "",
            "",
            [],
            104,
            "        path = self._normalize_path(path)",
            [],
            false
          ],
          [
            105,
            "",
            "",
            [],
            105,
            "",
            [],
            false
          ],
          [
            106,
            "",
            "",
            [],
            106,
            "        print &#39;PUTing to %s&#39; % path",
            [],
            false
          ],
          [
            107,
            "",
            "",
            [],
            107,
            "        print &quot;Post data: %s&quot; % query",
            [],
            false
          ],
          [
            108,
            "",
            "",
            [],
            108,
            "        response = self.api_func_wrapper(self.client.put, path, query,",
            [],
            false
          ],
          [
            109,
            "",
            "",
            [],
            109,
            "                                         expected_status, follow_redirects,",
            [],
            false
          ],
          [
            110,
            "",
            "",
            [],
            110,
            "                                         expected_redirects)",
            [],
            false
          ],
          [
            111,
            "",
            "",
            [],
            111,
            "        print &quot;Raw response: %s&quot; % response.content",
            [],
            false
          ],
          [
            112,
            "",
            "",
            [],
            112,
            "        self.assertEqual(response.status_code, expected_status)",
            [],
            false
          ],
          [
            113,
            "",
            "",
            [],
            113,
            "",
            [],
            false
          ],
          [
            114,
            "",
            "",
            [],
            114,
            "        return self._get_result(response, expected_status)",
            [],
            false
          ],
          [
            115,
            "",
            "",
            [],
            115,
            "",
            [],
            false
          ],
          [
            116,
            "",
            "",
            [],
            116,
            "    def apiDelete(self, path, expected_status=204):",
            [],
            false
          ],
          [
            117,
            "",
            "",
            [],
            117,
            "        path = self._normalize_path(path)",
            [],
            false
          ],
          [
            118,
            "",
            "",
            [],
            118,
            "",
            [],
            false
          ],
          [
            119,
            "",
            "",
            [],
            119,
            "        print &#39;DELETEing %s&#39; % path",
            [],
            false
          ],
          [
            120,
            "",
            "",
            [],
            120,
            "        response = self.client.delete(path)",
            [],
            false
          ],
          [
            121,
            "",
            "",
            [],
            121,
            "        print &quot;Raw response: %s&quot; % response.content",
            [],
            false
          ],
          [
            122,
            "",
            "",
            [],
            122,
            "        self.assertEqual(response.status_code, expected_status)",
            [],
            false
          ],
          [
            123,
            "",
            "",
            [],
            123,
            "",
            [],
            false
          ],
          [
            124,
            "",
            "",
            [],
            124,
            "        return self._get_result(response, expected_status)",
            [],
            false
          ],
          [
            125,
            "",
            "",
            [],
            125,
            "",
            [],
            false
          ],
          [
            126,
            "",
            "",
            [],
            126,
            "    def _normalize_path(self, path):",
            [],
            false
          ],
          [
            127,
            "",
            "",
            [],
            127,
            "        if path.startswith(self.base_url):",
            [],
            false
          ],
          [
            128,
            "",
            "",
            [],
            128,
            "            return path[len(self.base_url):]",
            [],
            false
          ],
          [
            129,
            "",
            "",
            [],
            129,
            "        else:",
            [],
            false
          ],
          [
            130,
            "",
            "",
            [],
            130,
            "            return path",
            [],
            false
          ],
          [
            131,
            "",
            "",
            [],
            131,
            "",
            [],
            false
          ],
          [
            132,
            "",
            "",
            [],
            132,
            "    def _get_result(self, response, expected_status):",
            [],
            false
          ],
          [
            133,
            "",
            "",
            [],
            133,
            "        if expected_status == 204:",
            [],
            false
          ],
          [
            134,
            "",
            "",
            [],
            134,
            "            self.assertEqual(response.content, &#39;&#39;)",
            [],
            false
          ],
          [
            135,
            "",
            "",
            [],
            135,
            "            rsp = None",
            [],
            false
          ],
          [
            136,
            "",
            "",
            [],
            136,
            "        else:",
            [],
            false
          ],
          [
            137,
            "",
            "",
            [],
            137,
            "            rsp = simplejson.loads(response.content)",
            [],
            false
          ],
          [
            138,
            "",
            "",
            [],
            138,
            "            print &quot;Response: %s&quot; % rsp",
            [],
            false
          ],
          [
            139,
            "",
            "",
            [],
            139,
            "",
            [],
            false
          ],
          [
            140,
            "",
            "",
            [],
            140,
            "        return rsp",
            [],
            false
          ],
          [
            141,
            "",
            "",
            [],
            141,
            "",
            [],
            false
          ],
          [
            142,
            "",
            "",
            [],
            142,
            "    #",
            [],
            false
          ],
          [
            143,
            "",
            "",
            [],
            143,
            "    # Some utility functions shared across test suites.",
            [],
            false
          ],
          [
            144,
            "",
            "",
            [],
            144,
            "    #",
            [],
            false
          ],
          [
            145,
            "",
            "",
            [],
            145,
            "    def _postNewReviewRequest(self, local_site_name=None,",
            [],
            false
          ],
          [
            146,
            "",
            "",
            [],
            146,
            "                              repository=None):",
            [],
            false
          ],
          [
            147,
            "",
            "",
            [],
            147,
            "        &quot;&quot;&quot;Creates a review request and returns the payload response.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            148,
            "",
            "",
            [],
            148,
            "        if not repository:",
            [],
            false
          ],
          [
            149,
            "",
            "",
            [],
            149,
            "            repository = self.repository",
            [],
            false
          ],
          [
            150,
            "",
            "",
            [],
            150,
            "        rsp = self.apiPost(",
            [],
            false
          ],
          [
            151,
            "",
            "",
            [],
            151,
            "            ReviewRequestResourceTests.get_list_url(local_site_name),",
            [],
            false
          ],
          [
            152,
            "",
            "",
            [],
            152,
            "            { &#39;repository&#39;: repository.path, })",
            [],
            false
          ],
          [
            153,
            "",
            "",
            [],
            153,
            "",
            [],
            false
          ],
          [
            154,
            "",
            "",
            [],
            154,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            155,
            "",
            "",
            [],
            155,
            "        self.assertEqual(",
            [],
            false
          ],
          [
            156,
            "",
            "",
            [],
            156,
            "            rsp[&#39;review_request&#39;][&#39;links&#39;][&#39;repository&#39;][&#39;href&#39;],",
            [],
            false
          ],
          [
            157,
            "",
            "",
            [],
            157,
            "            self.base_url +",
            [],
            false
          ],
          [
            158,
            "",
            "",
            [],
            158,
            "            RepositoryResourceTests.get_item_url(repository.id,",
            [],
            false
          ],
          [
            159,
            "",
            "",
            [],
            159,
            "                                                 local_site_name))",
            [],
            false
          ],
          [
            160,
            "",
            "",
            [],
            160,
            "",
            [],
            false
          ],
          [
            161,
            "",
            "",
            [],
            161,
            "        return rsp",
            [],
            false
          ],
          [
            162,
            "",
            "",
            [],
            162,
            "",
            [],
            false
          ],
          [
            163,
            "",
            "",
            [],
            163,
            "    def _postNewReview(self, review_request, body_top=&quot;&quot;,",
            [],
            false
          ],
          [
            164,
            "",
            "",
            [],
            164,
            "                       body_bottom=&quot;&quot;):",
            [],
            false
          ],
          [
            165,
            "",
            "",
            [],
            165,
            "        &quot;&quot;&quot;Creates a review and returns the payload response.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            166,
            "",
            "",
            [],
            166,
            "        if review_request.local_site:",
            [],
            false
          ],
          [
            167,
            "",
            "",
            [],
            167,
            "            local_site_name = review_request.local_site.name",
            [],
            false
          ],
          [
            168,
            "",
            "",
            [],
            168,
            "        else:",
            [],
            false
          ],
          [
            169,
            "",
            "",
            [],
            169,
            "            local_site_name = None",
            [],
            false
          ],
          [
            170,
            "",
            "",
            [],
            170,
            "",
            [],
            false
          ],
          [
            171,
            "",
            "",
            [],
            171,
            "        post_data = {",
            [],
            false
          ],
          [
            172,
            "",
            "",
            [],
            172,
            "            &#39;body_top&#39;: body_top,",
            [],
            false
          ],
          [
            173,
            "",
            "",
            [],
            173,
            "            &#39;body_bottom&#39;: body_bottom,",
            [],
            false
          ],
          [
            174,
            "",
            "",
            [],
            174,
            "        }",
            [],
            false
          ],
          [
            175,
            "",
            "",
            [],
            175,
            "",
            [],
            false
          ],
          [
            176,
            "",
            "",
            [],
            176,
            "        rsp = self.apiPost(ReviewResourceTests.get_list_url(review_request,",
            [],
            false
          ],
          [
            177,
            "",
            "",
            [],
            177,
            "                                                            local_site_name),",
            [],
            false
          ],
          [
            178,
            "",
            "",
            [],
            178,
            "                           post_data)",
            [],
            false
          ],
          [
            179,
            "",
            "",
            [],
            179,
            "",
            [],
            false
          ],
          [
            180,
            "",
            "",
            [],
            180,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            181,
            "",
            "",
            [],
            181,
            "        self.assertEqual(rsp[&#39;review&#39;][&#39;body_top&#39;], body_top)",
            [],
            false
          ],
          [
            182,
            "",
            "",
            [],
            182,
            "        self.assertEqual(rsp[&#39;review&#39;][&#39;body_bottom&#39;], body_bottom)",
            [],
            false
          ],
          [
            183,
            "",
            "",
            [],
            183,
            "",
            [],
            false
          ],
          [
            184,
            "",
            "",
            [],
            184,
            "        return rsp",
            [],
            false
          ],
          [
            185,
            "",
            "",
            [],
            185,
            "",
            [],
            false
          ],
          [
            186,
            "",
            "",
            [],
            186,
            "    def _postNewDiffComment(self, review_request, review_id, comment_text,",
            [],
            false
          ],
          [
            187,
            "",
            "",
            [],
            187,
            "                            filediff_id=None, interfilediff_id=None,",
            [],
            false
          ],
          [
            188,
            "",
            "",
            [],
            188,
            "                            first_line=10, num_lines=5):",
            [],
            false
          ],
          [
            189,
            "",
            "",
            [],
            189,
            "        &quot;&quot;&quot;Creates a diff comment and returns the payload response.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            190,
            "",
            "",
            [],
            190,
            "        if filediff_id is None:",
            [],
            false
          ],
          [
            191,
            "",
            "",
            [],
            191,
            "            diffset = review_request.diffset_history.diffsets.latest()",
            [],
            false
          ],
          [
            192,
            "",
            "",
            [],
            192,
            "            filediff = diffset.files.all()[0]",
            [],
            false
          ],
          [
            193,
            "",
            "",
            [],
            193,
            "            filediff_id = filediff.id",
            [],
            false
          ],
          [
            194,
            "",
            "",
            [],
            194,
            "",
            [],
            false
          ],
          [
            195,
            "",
            "",
            [],
            195,
            "        data = {",
            [],
            false
          ],
          [
            196,
            "",
            "",
            [],
            196,
            "            &#39;filediff_id&#39;: filediff_id,",
            [],
            false
          ],
          [
            197,
            "",
            "",
            [],
            197,
            "            &#39;text&#39;: comment_text,",
            [],
            false
          ],
          [
            198,
            "",
            "",
            [],
            198,
            "            &#39;first_line&#39;: first_line,",
            [],
            false
          ],
          [
            199,
            "",
            "",
            [],
            199,
            "            &#39;num_lines&#39;: num_lines,",
            [],
            false
          ],
          [
            200,
            "",
            "",
            [],
            200,
            "        }",
            [],
            false
          ],
          [
            201,
            "",
            "",
            [],
            201,
            "",
            [],
            false
          ],
          [
            202,
            "",
            "",
            [],
            202,
            "        if interfilediff_id is not None:",
            [],
            false
          ],
          [
            203,
            "",
            "",
            [],
            203,
            "            data[&#39;interfilediff_id&#39;] = interfilediff_id",
            [],
            false
          ],
          [
            204,
            "",
            "",
            [],
            204,
            "",
            [],
            false
          ],
          [
            205,
            "",
            "",
            [],
            205,
            "        if review_request.local_site:",
            [],
            false
          ],
          [
            206,
            "",
            "",
            [],
            206,
            "            local_site_name = review_request.local_site.name",
            [],
            false
          ],
          [
            207,
            "",
            "",
            [],
            207,
            "        else:",
            [],
            false
          ],
          [
            208,
            "",
            "",
            [],
            208,
            "            local_site_name = None",
            [],
            false
          ],
          [
            209,
            "",
            "",
            [],
            209,
            "",
            [],
            false
          ],
          [
            210,
            "",
            "",
            [],
            210,
            "        review = Review.objects.get(pk=review_id)",
            [],
            false
          ],
          [
            211,
            "",
            "",
            [],
            211,
            "",
            [],
            false
          ],
          [
            212,
            "",
            "",
            [],
            212,
            "        rsp = self.apiPost(",
            [],
            false
          ],
          [
            213,
            "",
            "",
            [],
            213,
            "            ReviewCommentResourceTests.get_list_url(review, local_site_name),",
            [],
            false
          ],
          [
            214,
            "",
            "",
            [],
            214,
            "            data)",
            [],
            false
          ],
          [
            215,
            "",
            "",
            [],
            215,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            216,
            "",
            "",
            [],
            216,
            "",
            [],
            false
          ],
          [
            217,
            "",
            "",
            [],
            217,
            "        return rsp",
            [],
            false
          ],
          [
            218,
            "",
            "",
            [],
            218,
            "",
            [],
            false
          ],
          [
            219,
            "",
            "",
            [],
            219,
            "    def _postNewScreenshotComment(self, review_request, review_id, screenshot,",
            [],
            false
          ],
          [
            220,
            "",
            "",
            [],
            220,
            "                                  comment_text, x, y, w, h):",
            [],
            false
          ],
          [
            221,
            "",
            "",
            [],
            221,
            "        &quot;&quot;&quot;Creates a screenshot comment and returns the payload response.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            222,
            "",
            "",
            [],
            222,
            "        if review_request.local_site:",
            [],
            false
          ],
          [
            223,
            "",
            "",
            [],
            223,
            "            local_site_name = review_request.local_site.name",
            [],
            false
          ],
          [
            224,
            "",
            "",
            [],
            224,
            "        else:",
            [],
            false
          ],
          [
            225,
            "",
            "",
            [],
            225,
            "            local_site_name = None",
            [],
            false
          ],
          [
            226,
            "",
            "",
            [],
            226,
            "",
            [],
            false
          ],
          [
            227,
            "",
            "",
            [],
            227,
            "        post_data = {",
            [],
            false
          ],
          [
            228,
            "",
            "",
            [],
            228,
            "            &#39;screenshot_id&#39;: screenshot.id,",
            [],
            false
          ],
          [
            229,
            "",
            "",
            [],
            229,
            "            &#39;text&#39;: comment_text,",
            [],
            false
          ],
          [
            230,
            "",
            "",
            [],
            230,
            "            &#39;x&#39;: x,",
            [],
            false
          ],
          [
            231,
            "",
            "",
            [],
            231,
            "            &#39;y&#39;: y,",
            [],
            false
          ],
          [
            232,
            "",
            "",
            [],
            232,
            "            &#39;w&#39;: w,",
            [],
            false
          ],
          [
            233,
            "",
            "",
            [],
            233,
            "            &#39;h&#39;: h,",
            [],
            false
          ],
          [
            234,
            "",
            "",
            [],
            234,
            "        }",
            [],
            false
          ],
          [
            235,
            "",
            "",
            [],
            235,
            "",
            [],
            false
          ],
          [
            236,
            "",
            "",
            [],
            236,
            "        review = Review.objects.get(pk=review_id)",
            [],
            false
          ],
          [
            237,
            "",
            "",
            [],
            237,
            "        rsp = self.apiPost(",
            [],
            false
          ],
          [
            238,
            "",
            "",
            [],
            238,
            "            DraftReviewScreenshotCommentResourceTests.get_list_url(",
            [],
            false
          ],
          [
            239,
            "",
            "",
            [],
            239,
            "                review, local_site_name),",
            [],
            false
          ],
          [
            240,
            "",
            "",
            [],
            240,
            "            post_data)",
            [],
            false
          ],
          [
            241,
            "",
            "",
            [],
            241,
            "",
            [],
            false
          ],
          [
            242,
            "",
            "",
            [],
            242,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            243,
            "",
            "",
            [],
            243,
            "",
            [],
            false
          ],
          [
            244,
            "",
            "",
            [],
            244,
            "        return rsp",
            [],
            false
          ],
          [
            245,
            "",
            "",
            [],
            245,
            "",
            [],
            false
          ],
          [
            246,
            "",
            "",
            [],
            246,
            "    def _postNewScreenshot(self, review_request):",
            [],
            false
          ],
          [
            247,
            "",
            "",
            [],
            247,
            "        &quot;&quot;&quot;Creates a screenshot and returns the payload response.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            248,
            "",
            "",
            [],
            248,
            "        if review_request.local_site:",
            [],
            false
          ],
          [
            249,
            "",
            "",
            [],
            249,
            "            local_site_name = review_request.local_site.name",
            [],
            false
          ],
          [
            250,
            "",
            "",
            [],
            250,
            "        else:",
            [],
            false
          ],
          [
            251,
            "",
            "",
            [],
            251,
            "            local_site_name = None",
            [],
            false
          ],
          [
            252,
            "",
            "",
            [],
            252,
            "",
            [],
            false
          ],
          [
            253,
            "",
            "",
            [],
            253,
            "        f = open(self._getTrophyFilename(), &quot;r&quot;)",
            [],
            false
          ],
          [
            254,
            "",
            "",
            [],
            254,
            "        self.assert_(f)",
            [],
            false
          ],
          [
            255,
            "",
            "",
            [],
            255,
            "",
            [],
            false
          ],
          [
            256,
            "",
            "",
            [],
            256,
            "        post_data = {",
            [],
            false
          ],
          [
            257,
            "",
            "",
            [],
            257,
            "            &#39;path&#39;: f,",
            [],
            false
          ],
          [
            258,
            "",
            "",
            [],
            258,
            "        }",
            [],
            false
          ],
          [
            259,
            "",
            "",
            [],
            259,
            "",
            [],
            false
          ],
          [
            260,
            "",
            "",
            [],
            260,
            "        rsp = self.apiPost(",
            [],
            false
          ],
          [
            261,
            "",
            "",
            [],
            261,
            "            ScreenshotResourceTests.get_list_url(review_request,",
            [],
            false
          ],
          [
            262,
            "",
            "",
            [],
            262,
            "                                                 local_site_name),",
            [],
            false
          ],
          [
            263,
            "",
            "",
            [],
            263,
            "            post_data)",
            [],
            false
          ],
          [
            264,
            "",
            "",
            [],
            264,
            "        f.close()",
            [],
            false
          ],
          [
            265,
            "",
            "",
            [],
            265,
            "",
            [],
            false
          ],
          [
            266,
            "",
            "",
            [],
            266,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            267,
            "",
            "",
            [],
            267,
            "",
            [],
            false
          ],
          [
            268,
            "",
            "",
            [],
            268,
            "        return rsp",
            [],
            false
          ],
          [
            269,
            "",
            "",
            [],
            269,
            "",
            [],
            false
          ],
          [
            270,
            "",
            "",
            [],
            270,
            "    def _postNewDiff(self, review_request):",
            [],
            false
          ],
          [
            271,
            "",
            "",
            [],
            271,
            "        &quot;&quot;&quot;Creates a diff and returns the payload response.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            272,
            "",
            "",
            [],
            272,
            "        diff_filename = os.path.join(",
            [],
            false
          ],
          [
            273,
            "",
            "",
            [],
            273,
            "            os.path.dirname(os.path.dirname(__file__)),",
            [],
            false
          ],
          [
            274,
            "",
            "",
            [],
            274,
            "            &quot;scmtools&quot;, &quot;testdata&quot;, &quot;svn_makefile.diff&quot;)",
            [],
            false
          ],
          [
            275,
            "",
            "",
            [],
            275,
            "",
            [],
            false
          ],
          [
            276,
            "",
            "",
            [],
            276,
            "        f = open(diff_filename, &quot;r&quot;)",
            [],
            false
          ],
          [
            277,
            "",
            "",
            [],
            277,
            "        rsp = self.apiPost(DiffResourceTests.get_list_url(review_request), {",
            [],
            false
          ],
          [
            278,
            "",
            "",
            [],
            278,
            "            &#39;path&#39;: f,",
            [],
            false
          ],
          [
            279,
            "",
            "",
            [],
            279,
            "            &#39;basedir&#39;: &quot;/trunk&quot;,",
            [],
            false
          ],
          [
            280,
            "",
            "",
            [],
            280,
            "        })",
            [],
            false
          ],
          [
            281,
            "",
            "",
            [],
            281,
            "        f.close()",
            [],
            false
          ],
          [
            282,
            "",
            "",
            [],
            282,
            "",
            [],
            false
          ],
          [
            283,
            "",
            "",
            [],
            283,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            284,
            "",
            "",
            [],
            284,
            "",
            [],
            false
          ],
          [
            285,
            "",
            "",
            [],
            285,
            "        return rsp",
            [],
            false
          ],
          [
            286,
            "",
            "",
            [],
            286,
            "",
            [],
            false
          ],
          [
            287,
            "",
            "",
            [],
            287,
            "    def _getTrophyFilename(self):",
            [],
            false
          ],
          [
            288,
            "",
            "",
            [],
            288,
            "        return os.path.join(settings.HTDOCS_ROOT,",
            [],
            false
          ],
          [
            289,
            "",
            "",
            [],
            289,
            "                            &quot;media&quot;, &quot;rb&quot;, &quot;images&quot;, &quot;trophy.png&quot;)",
            [],
            false
          ],
          [
            290,
            "",
            "",
            [],
            290,
            "",
            [],
            false
          ],
          [
            291,
            "",
            "",
            [],
            291,
            "",
            [],
            false
          ],
          [
            292,
            "",
            "",
            [],
            292,
            "class ServerInfoResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            293,
            "",
            "",
            [],
            293,
            "    &quot;&quot;&quot;Testing the ServerInfoResource APIs.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            294,
            "",
            "",
            [],
            294,
            "    def test_get_server_info(self):",
            [],
            false
          ],
          [
            295,
            "",
            "",
            [],
            295,
            "        &quot;&quot;&quot;Testing the GET info/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            296,
            "",
            "",
            [],
            296,
            "        rsp = self.apiGet(self.get_url())",
            [],
            false
          ],
          [
            297,
            "",
            "",
            [],
            297,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            298,
            "",
            "",
            [],
            298,
            "        self.assertTrue(&#39;info&#39; in rsp)",
            [],
            false
          ],
          [
            299,
            "",
            "",
            [],
            299,
            "        self.assertTrue(&#39;product&#39; in rsp[&#39;info&#39;])",
            [],
            false
          ],
          [
            300,
            "",
            "",
            [],
            300,
            "        self.assertTrue(&#39;site&#39; in rsp[&#39;info&#39;])",
            [],
            false
          ],
          [
            301,
            "",
            "",
            [],
            301,
            "",
            [],
            false
          ],
          [
            302,
            "",
            "",
            [],
            302,
            "    def test_get_server_info_with_site(self):",
            [],
            false
          ],
          [
            303,
            "",
            "",
            [],
            303,
            "        &quot;&quot;&quot;Testing the GET info/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            304,
            "",
            "",
            [],
            304,
            "        self.client.logout()",
            [],
            false
          ],
          [
            305,
            "",
            "",
            [],
            305,
            "        self.client.login(username=&quot;doc&quot;, password=&quot;doc&quot;)",
            [],
            false
          ],
          [
            306,
            "",
            "",
            [],
            306,
            "",
            [],
            false
          ],
          [
            307,
            "",
            "",
            [],
            307,
            "        rsp = self.apiGet(self.get_url(self.local_site_name))",
            [],
            false
          ],
          [
            308,
            "",
            "",
            [],
            308,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            309,
            "",
            "",
            [],
            309,
            "        self.assertTrue(&#39;info&#39; in rsp)",
            [],
            false
          ],
          [
            310,
            "",
            "",
            [],
            310,
            "        self.assertTrue(&#39;product&#39; in rsp[&#39;info&#39;])",
            [],
            false
          ],
          [
            311,
            "",
            "",
            [],
            311,
            "        self.assertTrue(&#39;site&#39; in rsp[&#39;info&#39;])",
            [],
            false
          ],
          [
            312,
            "",
            "",
            [],
            312,
            "",
            [],
            false
          ],
          [
            313,
            "",
            "",
            [],
            313,
            "    def test_get_server_info_with_site_no_access(self):",
            [],
            false
          ],
          [
            314,
            "",
            "",
            [],
            314,
            "        &quot;&quot;&quot;Testing the GET info/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            315,
            "",
            "",
            [],
            315,
            "        self.apiGet(self.get_url(self.local_site_name),",
            [],
            false
          ],
          [
            316,
            "",
            "",
            [],
            316,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            317,
            "",
            "",
            [],
            317,
            "",
            [],
            false
          ],
          [
            318,
            "",
            "",
            [],
            318,
            "    def get_url(self, local_site_name=None):",
            [],
            false
          ],
          [
            319,
            "",
            "",
            [],
            319,
            "        return local_site_reverse(&#39;info-resource&#39;,",
            [],
            false
          ],
          [
            320,
            "",
            "",
            [],
            320,
            "                                  local_site_name=local_site_name)",
            [],
            false
          ],
          [
            321,
            "",
            "",
            [],
            321,
            "",
            [],
            false
          ],
          [
            322,
            "",
            "",
            [],
            322,
            "",
            [],
            false
          ],
          [
            323,
            "",
            "",
            [],
            323,
            "class SessionResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            324,
            "",
            "",
            [],
            324,
            "    &quot;&quot;&quot;Testing the SessionResource APIs.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            325,
            "",
            "",
            [],
            325,
            "    def test_get_session_with_logged_in_user(self):",
            [],
            false
          ],
          [
            326,
            "",
            "",
            [],
            326,
            "        &quot;&quot;&quot;Testing the GET session/ API with logged in user&quot;&quot;&quot;",
            [],
            false
          ],
          [
            327,
            "",
            "",
            [],
            327,
            "        rsp = self.apiGet(self.get_url())",
            [],
            false
          ],
          [
            328,
            "",
            "",
            [],
            328,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            329,
            "",
            "",
            [],
            329,
            "        self.assertTrue(&#39;session&#39; in rsp)",
            [],
            false
          ],
          [
            330,
            "",
            "",
            [],
            330,
            "        self.assertTrue(rsp[&#39;session&#39;][&#39;authenticated&#39;])",
            [],
            false
          ],
          [
            331,
            "",
            "",
            [],
            331,
            "        self.assertEqual(rsp[&#39;session&#39;][&#39;links&#39;][&#39;user&#39;][&#39;title&#39;],",
            [],
            false
          ],
          [
            332,
            "",
            "",
            [],
            332,
            "                         self.user.username)",
            [],
            false
          ],
          [
            333,
            "",
            "",
            [],
            333,
            "",
            [],
            false
          ],
          [
            334,
            "",
            "",
            [],
            334,
            "    def test_get_session_with_anonymous_user(self):",
            [],
            false
          ],
          [
            335,
            "",
            "",
            [],
            335,
            "        &quot;&quot;&quot;Testing the GET session/ API with anonymous user&quot;&quot;&quot;",
            [],
            false
          ],
          [
            336,
            "",
            "",
            [],
            336,
            "        self.client.logout()",
            [],
            false
          ],
          [
            337,
            "",
            "",
            [],
            337,
            "",
            [],
            false
          ],
          [
            338,
            "",
            "",
            [],
            338,
            "        rsp = self.apiGet(self.get_url())",
            [],
            false
          ],
          [
            339,
            "",
            "",
            [],
            339,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            340,
            "",
            "",
            [],
            340,
            "        self.assertTrue(&#39;session&#39; in rsp)",
            [],
            false
          ],
          [
            341,
            "",
            "",
            [],
            341,
            "        self.assertFalse(rsp[&#39;session&#39;][&#39;authenticated&#39;])",
            [],
            false
          ],
          [
            342,
            "",
            "",
            [],
            342,
            "",
            [],
            false
          ],
          [
            343,
            "",
            "",
            [],
            343,
            "    def test_get_session_with_site(self):",
            [],
            false
          ],
          [
            344,
            "",
            "",
            [],
            344,
            "        &quot;&quot;&quot;Testing the GET session/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            345,
            "",
            "",
            [],
            345,
            "        self.client.logout()",
            [],
            false
          ],
          [
            346,
            "",
            "",
            [],
            346,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            347,
            "",
            "",
            [],
            347,
            "",
            [],
            false
          ],
          [
            348,
            "",
            "",
            [],
            348,
            "        rsp = self.apiGet(self.get_url(self.local_site_name))",
            [],
            false
          ],
          [
            349,
            "",
            "",
            [],
            349,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            350,
            "",
            "",
            [],
            350,
            "        self.assertTrue(&#39;session&#39; in rsp)",
            [],
            false
          ],
          [
            351,
            "",
            "",
            [],
            351,
            "        self.assertTrue(rsp[&#39;session&#39;][&#39;authenticated&#39;])",
            [],
            false
          ],
          [
            352,
            "",
            "",
            [],
            352,
            "        self.assertEqual(rsp[&#39;session&#39;][&#39;links&#39;][&#39;user&#39;][&#39;title&#39;], &#39;doc&#39;)",
            [],
            false
          ],
          [
            353,
            "",
            "",
            [],
            353,
            "",
            [],
            false
          ],
          [
            354,
            "",
            "",
            [],
            354,
            "    def test_get_session_with_site_no_access(self):",
            [],
            false
          ],
          [
            355,
            "",
            "",
            [],
            355,
            "        &quot;&quot;&quot;Testing the GET session/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            356,
            "",
            "",
            [],
            356,
            "        self.apiGet(self.get_url(self.local_site_name),",
            [],
            false
          ],
          [
            357,
            "",
            "",
            [],
            357,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            358,
            "",
            "",
            [],
            358,
            "",
            [],
            false
          ],
          [
            359,
            "",
            "",
            [],
            359,
            "    def get_url(self, local_site_name=None):",
            [],
            false
          ],
          [
            360,
            "",
            "",
            [],
            360,
            "        return local_site_reverse(&#39;session-resource&#39;,",
            [],
            false
          ],
          [
            361,
            "",
            "",
            [],
            361,
            "                                  local_site_name=local_site_name)",
            [],
            false
          ],
          [
            362,
            "",
            "",
            [],
            362,
            "",
            [],
            false
          ],
          [
            363,
            "",
            "",
            [],
            363,
            "",
            [],
            false
          ],
          [
            364,
            "",
            "",
            [],
            364,
            "class RepositoryResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            365,
            "",
            "",
            [],
            365,
            "    &quot;&quot;&quot;Testing the RepositoryResource APIs.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            366,
            "",
            "",
            [],
            366,
            "",
            [],
            false
          ],
          [
            367,
            "",
            "",
            [],
            367,
            "    def test_get_repositories(self):",
            [],
            false
          ],
          [
            368,
            "",
            "",
            [],
            368,
            "        &quot;&quot;&quot;Testing the GET repositories/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            369,
            "",
            "",
            [],
            369,
            "        rsp = self.apiGet(self.get_list_url())",
            [],
            false
          ],
          [
            370,
            "",
            "",
            [],
            370,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            371,
            "",
            "",
            [],
            371,
            "        self.assertEqual(len(rsp[&#39;repositories&#39;]),",
            [],
            false
          ],
          [
            372,
            "",
            "",
            [],
            372,
            "                         Repository.objects.accessible(self.user).count())",
            [],
            false
          ],
          [
            373,
            "",
            "",
            [],
            373,
            "",
            [],
            false
          ],
          [
            374,
            "",
            "",
            [],
            374,
            "    def test_get_repositories_with_site(self):",
            [],
            false
          ],
          [
            375,
            "",
            "",
            [],
            375,
            "        &quot;&quot;&quot;Testing the GET repositories/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            376,
            "",
            "",
            [],
            376,
            "        self.client.logout()",
            [],
            false
          ],
          [
            377,
            "",
            "",
            [],
            377,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            378,
            "",
            "",
            [],
            378,
            "",
            [],
            false
          ],
          [
            379,
            "",
            "",
            [],
            379,
            "        rsp = self.apiGet(self.get_list_url(self.local_site_name))",
            [],
            false
          ],
          [
            380,
            "",
            "",
            [],
            380,
            "        self.assertEqual(len(rsp[&#39;repositories&#39;]),",
            [],
            false
          ],
          [
            381,
            "",
            "",
            [],
            381,
            "                         Repository.objects.filter(",
            [],
            false
          ],
          [
            382,
            "",
            "",
            [],
            382,
            "                             local_site__name=self.local_site_name).count())",
            [],
            false
          ],
          [
            383,
            "",
            "",
            [],
            383,
            "",
            [],
            false
          ],
          [
            384,
            "",
            "",
            [],
            384,
            "    def test_get_repositories_with_site_no_access(self):",
            [],
            false
          ],
          [
            385,
            "",
            "",
            [],
            385,
            "        &quot;&quot;&quot;Testing the GET repositories/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            386,
            "",
            "",
            [],
            386,
            "        self.apiGet(self.get_list_url(self.local_site_name),",
            [],
            false
          ],
          [
            387,
            "",
            "",
            [],
            387,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            388,
            "",
            "",
            [],
            388,
            "",
            [],
            false
          ],
          [
            389,
            "",
            "",
            [],
            389,
            "    def get_list_url(self, local_site_name=None):",
            [],
            false
          ],
          [
            390,
            "",
            "",
            [],
            390,
            "        return local_site_reverse(&#39;repositories-resource&#39;,",
            [],
            false
          ],
          [
            391,
            "",
            "",
            [],
            391,
            "                                  local_site_name=local_site_name)",
            [],
            false
          ],
          [
            392,
            "",
            "",
            [],
            392,
            "",
            [],
            false
          ],
          [
            393,
            "",
            "",
            [],
            393,
            "    @classmethod",
            [],
            false
          ],
          [
            394,
            "",
            "",
            [],
            394,
            "    def get_item_url(cls, repository_id, local_site_name=None):",
            [],
            false
          ],
          [
            395,
            "",
            "",
            [],
            395,
            "        return local_site_reverse(&#39;repository-resource&#39;,",
            [],
            false
          ],
          [
            396,
            "",
            "",
            [],
            396,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            397,
            "",
            "",
            [],
            397,
            "                                  kwargs={",
            [],
            false
          ],
          [
            398,
            "",
            "",
            [],
            398,
            "                                      &#39;repository_id&#39;: repository_id,",
            [],
            false
          ],
          [
            399,
            "",
            "",
            [],
            399,
            "                                  })",
            [],
            false
          ],
          [
            400,
            "",
            "",
            [],
            400,
            "",
            [],
            false
          ],
          [
            401,
            "",
            "",
            [],
            401,
            "",
            [],
            false
          ],
          [
            402,
            "",
            "",
            [],
            402,
            "class RepositoryInfoResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            403,
            "",
            "",
            [],
            403,
            "    &quot;&quot;&quot;Testing the RepositoryInfoResource APIs.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            404,
            "",
            "",
            [],
            404,
            "    def test_get_repository_info(self):",
            [],
            false
          ],
          [
            405,
            "",
            "",
            [],
            405,
            "        &quot;&quot;&quot;Testing the GET repositories/&lt;id&gt;/info API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            406,
            "",
            "",
            [],
            406,
            "        rsp = self.apiGet(self.get_url(self.repository))",
            [],
            false
          ],
          [
            407,
            "",
            "",
            [],
            407,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            408,
            "",
            "",
            [],
            408,
            "        self.assertEqual(rsp[&#39;info&#39;],",
            [],
            false
          ],
          [
            409,
            "",
            "",
            [],
            409,
            "                         self.repository.get_scmtool().get_repository_info())",
            [],
            false
          ],
          [
            410,
            "",
            "",
            [],
            410,
            "",
            [],
            false
          ],
          [
            411,
            "",
            "",
            [],
            411,
            "    def test_get_repository_info_with_site(self):",
            [],
            false
          ],
          [
            412,
            "",
            "",
            [],
            412,
            "        &quot;&quot;&quot;Testing the GET repositories/&lt;id&gt;/info API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            413,
            "",
            "",
            [],
            413,
            "        self.client.logout()",
            [],
            false
          ],
          [
            414,
            "",
            "",
            [],
            414,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            415,
            "",
            "",
            [],
            415,
            "",
            [],
            false
          ],
          [
            416,
            "",
            "",
            [],
            416,
            "        repository = Repository.objects.get(name=&#39;V8 SVN&#39;)",
            [],
            false
          ],
          [
            417,
            "",
            "",
            [],
            417,
            "        rsp = self.apiGet(self.get_url(repository, self.local_site_name))",
            [],
            false
          ],
          [
            418,
            "",
            "",
            [],
            418,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            419,
            "",
            "",
            [],
            419,
            "        self.assertEqual(rsp[&#39;info&#39;],",
            [],
            false
          ],
          [
            420,
            "",
            "",
            [],
            420,
            "                         repository.get_scmtool().get_repository_info())",
            [],
            false
          ],
          [
            421,
            "",
            "",
            [],
            421,
            "",
            [],
            false
          ],
          [
            422,
            "",
            "",
            [],
            422,
            "    def test_get_repository_info_with_site_no_access(self):",
            [],
            false
          ],
          [
            423,
            "",
            "",
            [],
            423,
            "        &quot;&quot;&quot;Testing the GET repositories/&lt;id&gt;/info API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            424,
            "",
            "",
            [],
            424,
            "        repository = Repository.objects.get(name=&#39;V8 SVN&#39;)",
            [],
            false
          ],
          [
            425,
            "",
            "",
            [],
            425,
            "",
            [],
            false
          ],
          [
            426,
            "",
            "",
            [],
            426,
            "        self.apiGet(self.get_url(self.repository, self.local_site_name),",
            [],
            false
          ],
          [
            427,
            "",
            "",
            [],
            427,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            428,
            "",
            "",
            [],
            428,
            "",
            [],
            false
          ],
          [
            429,
            "",
            "",
            [],
            429,
            "    def get_url(self, repository, local_site_name=None):",
            [],
            false
          ],
          [
            430,
            "",
            "",
            [],
            430,
            "        return local_site_reverse(&#39;info-resource&#39;,",
            [],
            false
          ],
          [
            431,
            "",
            "",
            [],
            431,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            432,
            "",
            "",
            [],
            432,
            "                                  kwargs={",
            [],
            false
          ],
          [
            433,
            "",
            "",
            [],
            433,
            "                                      &#39;repository_id&#39;: repository.pk,",
            [],
            false
          ],
          [
            434,
            "",
            "",
            [],
            434,
            "                                  })",
            [],
            false
          ],
          [
            435,
            "",
            "",
            [],
            435,
            "",
            [],
            false
          ],
          [
            436,
            "",
            "",
            [],
            436,
            "",
            [],
            false
          ],
          [
            437,
            "",
            "",
            [],
            437,
            "class ReviewGroupResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            438,
            "",
            "",
            [],
            438,
            "    &quot;&quot;&quot;Testing the ReviewGroupResource APIs.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            439,
            "",
            "",
            [],
            439,
            "",
            [],
            false
          ],
          [
            440,
            "",
            "",
            [],
            440,
            "    def test_get_groups(self):",
            [],
            false
          ],
          [
            441,
            "",
            "",
            [],
            441,
            "        &quot;&quot;&quot;Testing the GET groups/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            442,
            "",
            "",
            [],
            442,
            "        rsp = self.apiGet(self.get_list_url())",
            [],
            false
          ],
          [
            443,
            "",
            "",
            [],
            443,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            444,
            "",
            "",
            [],
            444,
            "        self.assertEqual(len(rsp[&#39;groups&#39;]),",
            [],
            false
          ],
          [
            445,
            "",
            "",
            [],
            445,
            "                         Group.objects.accessible(self.user).count())",
            [],
            false
          ],
          [
            446,
            "",
            "",
            [],
            446,
            "        self.assertEqual(len(rsp[&#39;groups&#39;]), 4)",
            [],
            false
          ],
          [
            447,
            "",
            "",
            [],
            447,
            "",
            [],
            false
          ],
          [
            448,
            "",
            "",
            [],
            448,
            "    def test_get_groups_with_site(self):",
            [],
            false
          ],
          [
            449,
            "",
            "",
            [],
            449,
            "        &quot;&quot;&quot;Testing the GET groups/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            450,
            "",
            "",
            [],
            450,
            "        self.client.logout()",
            [],
            false
          ],
          [
            451,
            "",
            "",
            [],
            451,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            452,
            "",
            "",
            [],
            452,
            "",
            [],
            false
          ],
          [
            453,
            "",
            "",
            [],
            453,
            "        local_site = LocalSite.objects.get(name=self.local_site_name)",
            [],
            false
          ],
          [
            454,
            "",
            "",
            [],
            454,
            "        groups = Group.objects.accessible(self.user, local_site=local_site)",
            [],
            false
          ],
          [
            455,
            "",
            "",
            [],
            455,
            "",
            [],
            false
          ],
          [
            456,
            "",
            "",
            [],
            456,
            "        rsp = self.apiGet(self.get_list_url(self.local_site_name))",
            [],
            false
          ],
          [
            457,
            "",
            "",
            [],
            457,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            458,
            "",
            "",
            [],
            458,
            "        self.assertEqual(len(rsp[&#39;groups&#39;]), groups.count())",
            [],
            false
          ],
          [
            459,
            "",
            "",
            [],
            459,
            "        self.assertEqual(len(rsp[&#39;groups&#39;]), 1)",
            [],
            false
          ],
          [
            460,
            "",
            "",
            [],
            460,
            "",
            [],
            false
          ],
          [
            461,
            "",
            "",
            [],
            461,
            "    def test_get_groups_with_site_no_access(self):",
            [],
            false
          ],
          [
            462,
            "",
            "",
            [],
            462,
            "        &quot;&quot;&quot;Testing the GET groups/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            463,
            "",
            "",
            [],
            463,
            "        self.apiGet(self.get_list_url(self.local_site_name),",
            [],
            false
          ],
          [
            464,
            "",
            "",
            [],
            464,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            465,
            "",
            "",
            [],
            465,
            "",
            [],
            false
          ],
          [
            466,
            "",
            "",
            [],
            466,
            "    def test_get_groups_with_q(self):",
            [],
            false
          ],
          [
            467,
            "",
            "",
            [],
            467,
            "        &quot;&quot;&quot;Testing the GET groups/?q= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            468,
            "",
            "",
            [],
            468,
            "        rsp = self.apiGet(self.get_list_url(), {&#39;q&#39;: &#39;dev&#39;})",
            [],
            false
          ],
          [
            469,
            "",
            "",
            [],
            469,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            470,
            "",
            "",
            [],
            470,
            "        self.assertEqual(len(rsp[&#39;groups&#39;]), 1) #devgroup",
            [],
            false
          ],
          [
            471,
            "",
            "",
            [],
            471,
            "",
            [],
            false
          ],
          [
            472,
            "",
            "",
            [],
            472,
            "    def test_get_group_public(self):",
            [],
            false
          ],
          [
            473,
            "",
            "",
            [],
            473,
            "        &quot;&quot;&quot;Testing the GET groups/&lt;id&gt;/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            474,
            "",
            "",
            [],
            474,
            "        group = Group.objects.create(name=&#39;test-group&#39;)",
            [],
            false
          ],
          [
            475,
            "",
            "",
            [],
            475,
            "",
            [],
            false
          ],
          [
            476,
            "",
            "",
            [],
            476,
            "        rsp = self.apiGet(self.get_item_url(group.name))",
            [],
            false
          ],
          [
            477,
            "",
            "",
            [],
            477,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            478,
            "",
            "",
            [],
            478,
            "        self.assertEqual(rsp[&#39;group&#39;][&#39;name&#39;], group.name)",
            [],
            false
          ],
          [
            479,
            "",
            "",
            [],
            479,
            "        self.assertEqual(rsp[&#39;group&#39;][&#39;display_name&#39;], group.display_name)",
            [],
            false
          ],
          [
            480,
            "",
            "",
            [],
            480,
            "        self.assertEqual(rsp[&#39;group&#39;][&#39;invite_only&#39;], False)",
            [],
            false
          ],
          [
            481,
            "",
            "",
            [],
            481,
            "",
            [],
            false
          ],
          [
            482,
            "",
            "",
            [],
            482,
            "    def test_get_group_invite_only(self):",
            [],
            false
          ],
          [
            483,
            "",
            "",
            [],
            483,
            "        &quot;&quot;&quot;Testing the GET groups/&lt;id&gt;/ API with invite-only&quot;&quot;&quot;",
            [],
            false
          ],
          [
            484,
            "",
            "",
            [],
            484,
            "        group = Group.objects.create(name=&#39;test-group&#39;, invite_only=True)",
            [],
            false
          ],
          [
            485,
            "",
            "",
            [],
            485,
            "        group.users.add(self.user)",
            [],
            false
          ],
          [
            486,
            "",
            "",
            [],
            486,
            "",
            [],
            false
          ],
          [
            487,
            "",
            "",
            [],
            487,
            "        rsp = self.apiGet(self.get_item_url(group.name))",
            [],
            false
          ],
          [
            488,
            "",
            "",
            [],
            488,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            489,
            "",
            "",
            [],
            489,
            "        self.assertEqual(rsp[&#39;group&#39;][&#39;invite_only&#39;], True)",
            [],
            false
          ],
          [
            490,
            "",
            "",
            [],
            490,
            "",
            [],
            false
          ],
          [
            491,
            "",
            "",
            [],
            491,
            "    def test_get_group_invite_only_with_permission_denied_error(self):",
            [],
            false
          ],
          [
            492,
            "",
            "",
            [],
            492,
            "        &quot;&quot;&quot;Testing the GET groups/&lt;id&gt;/ API with invite-only and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            493,
            "",
            "",
            [],
            493,
            "        group = Group.objects.create(name=&#39;test-group&#39;, invite_only=True)",
            [],
            false
          ],
          [
            494,
            "",
            "",
            [],
            494,
            "",
            [],
            false
          ],
          [
            495,
            "",
            "",
            [],
            495,
            "        rsp = self.apiGet(self.get_item_url(group.name),",
            [],
            false
          ],
          [
            496,
            "",
            "",
            [],
            496,
            "                          expected_status=403)",
            [],
            false
          ],
          [
            497,
            "",
            "",
            [],
            497,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            498,
            "",
            "",
            [],
            498,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], PERMISSION_DENIED.code)",
            [],
            false
          ],
          [
            499,
            "",
            "",
            [],
            499,
            "",
            [],
            false
          ],
          [
            500,
            "",
            "",
            [],
            500,
            "    def test_get_group_with_site(self):",
            [],
            false
          ],
          [
            501,
            "",
            "",
            [],
            501,
            "        &quot;&quot;&quot;Testing the GET groups/&lt;id&gt;/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            502,
            "",
            "",
            [],
            502,
            "        self.client.logout()",
            [],
            false
          ],
          [
            503,
            "",
            "",
            [],
            503,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            504,
            "",
            "",
            [],
            504,
            "",
            [],
            false
          ],
          [
            505,
            "",
            "",
            [],
            505,
            "        group = Group.objects.get(name=&#39;sitegroup&#39;)",
            [],
            false
          ],
          [
            506,
            "",
            "",
            [],
            506,
            "",
            [],
            false
          ],
          [
            507,
            "",
            "",
            [],
            507,
            "        rsp = self.apiGet(self.get_item_url(&#39;sitegroup&#39;, self.local_site_name))",
            [],
            false
          ],
          [
            508,
            "",
            "",
            [],
            508,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            509,
            "",
            "",
            [],
            509,
            "        self.assertEqual(rsp[&#39;group&#39;][&#39;name&#39;], group.name)",
            [],
            false
          ],
          [
            510,
            "",
            "",
            [],
            510,
            "        self.assertEqual(rsp[&#39;group&#39;][&#39;display_name&#39;], group.display_name)",
            [],
            false
          ],
          [
            511,
            "",
            "",
            [],
            511,
            "",
            [],
            false
          ],
          [
            512,
            "",
            "",
            [],
            512,
            "    def test_get_group_with_site_no_access(self):",
            [],
            false
          ],
          [
            513,
            "",
            "",
            [],
            513,
            "        &quot;&quot;&quot;Testing the GET groups/&lt;id&gt;/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            514,
            "",
            "",
            [],
            514,
            "        self.apiGet(self.get_item_url(&#39;sitegroup&#39;, self.local_site_name),",
            [],
            false
          ],
          [
            515,
            "",
            "",
            [],
            515,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            516,
            "",
            "",
            [],
            516,
            "",
            [],
            false
          ],
          [
            517,
            "",
            "",
            [],
            517,
            "    def get_list_url(self, local_site_name=None):",
            [],
            false
          ],
          [
            518,
            "",
            "",
            [],
            518,
            "        return local_site_reverse(&#39;groups-resource&#39;,",
            [],
            false
          ],
          [
            519,
            "",
            "",
            [],
            519,
            "                                  local_site_name=local_site_name)",
            [],
            false
          ],
          [
            520,
            "",
            "",
            [],
            520,
            "",
            [],
            false
          ],
          [
            521,
            "",
            "",
            [],
            521,
            "    def get_item_url(self, group_name, local_site_name=None):",
            [],
            false
          ],
          [
            522,
            "",
            "",
            [],
            522,
            "        return local_site_reverse(&#39;group-resource&#39;,",
            [],
            false
          ],
          [
            523,
            "",
            "",
            [],
            523,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            524,
            "",
            "",
            [],
            524,
            "                                  kwargs={",
            [],
            false
          ],
          [
            525,
            "",
            "",
            [],
            525,
            "                                      &#39;group_name&#39;: group_name,",
            [],
            false
          ],
          [
            526,
            "",
            "",
            [],
            526,
            "                                  })",
            [],
            false
          ],
          [
            527,
            "",
            "",
            [],
            527,
            "",
            [],
            false
          ],
          [
            528,
            "",
            "",
            [],
            528,
            "",
            [],
            false
          ],
          [
            529,
            "",
            "",
            [],
            529,
            "class UserResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            530,
            "",
            "",
            [],
            530,
            "    &quot;&quot;&quot;Testing the UserResource API tests.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            531,
            "",
            "",
            [],
            531,
            "",
            [],
            false
          ],
          [
            532,
            "",
            "",
            [],
            532,
            "    def test_get_users(self):",
            [],
            false
          ],
          [
            533,
            "",
            "",
            [],
            533,
            "        &quot;&quot;&quot;Testing the GET users/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            534,
            "",
            "",
            [],
            534,
            "        rsp = self.apiGet(self.get_list_url())",
            [],
            false
          ],
          [
            535,
            "",
            "",
            [],
            535,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            536,
            "",
            "",
            [],
            536,
            "        self.assertEqual(len(rsp[&#39;users&#39;]), User.objects.count())",
            [],
            false
          ],
          [
            537,
            "",
            "",
            [],
            537,
            "",
            [],
            false
          ],
          [
            538,
            "",
            "",
            [],
            538,
            "    def test_get_users_with_q(self):",
            [],
            false
          ],
          [
            539,
            "",
            "",
            [],
            539,
            "        &quot;&quot;&quot;Testing the GET users/?q= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            540,
            "",
            "",
            [],
            540,
            "        rsp = self.apiGet(self.get_list_url(), {&#39;q&#39;: &#39;gru&#39;})",
            [],
            false
          ],
          [
            541,
            "",
            "",
            [],
            541,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            542,
            "",
            "",
            [],
            542,
            "        self.assertEqual(len(rsp[&#39;users&#39;]), 1) # grumpy",
            [],
            false
          ],
          [
            543,
            "",
            "",
            [],
            543,
            "",
            [],
            false
          ],
          [
            544,
            "",
            "",
            [],
            544,
            "    def test_get_users_with_site(self):",
            [],
            false
          ],
          [
            545,
            "",
            "",
            [],
            545,
            "        &quot;&quot;&quot;Testing the GET users/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            546,
            "",
            "",
            [],
            546,
            "        self.client.logout()",
            [],
            false
          ],
          [
            547,
            "",
            "",
            [],
            547,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            548,
            "",
            "",
            [],
            548,
            "",
            [],
            false
          ],
          [
            549,
            "",
            "",
            [],
            549,
            "        local_site = LocalSite.objects.get(name=self.local_site_name)",
            [],
            false
          ],
          [
            550,
            "",
            "",
            [],
            550,
            "        rsp = self.apiGet(self.get_list_url(self.local_site_name))",
            [],
            false
          ],
          [
            551,
            "",
            "",
            [],
            551,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            552,
            "",
            "",
            [],
            552,
            "        self.assertEqual(len(rsp[&#39;users&#39;]), local_site.users.count())",
            [],
            false
          ],
          [
            553,
            "",
            "",
            [],
            553,
            "",
            [],
            false
          ],
          [
            554,
            "",
            "",
            [],
            554,
            "    def test_get_users_with_site_no_access(self):",
            [],
            false
          ],
          [
            555,
            "",
            "",
            [],
            555,
            "        &quot;&quot;&quot;Testing the GET users/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            556,
            "",
            "",
            [],
            556,
            "        self.apiGet(self.get_list_url(self.local_site_name),",
            [],
            false
          ],
          [
            557,
            "",
            "",
            [],
            557,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            558,
            "",
            "",
            [],
            558,
            "",
            [],
            false
          ],
          [
            559,
            "",
            "",
            [],
            559,
            "    def test_get_user(self):",
            [],
            false
          ],
          [
            560,
            "",
            "",
            [],
            560,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            561,
            "",
            "",
            [],
            561,
            "        username = &#39;doc&#39;",
            [],
            false
          ],
          [
            562,
            "",
            "",
            [],
            562,
            "        user = User.objects.get(username=username)",
            [],
            false
          ],
          [
            563,
            "",
            "",
            [],
            563,
            "",
            [],
            false
          ],
          [
            564,
            "",
            "",
            [],
            564,
            "        rsp = self.apiGet(self.get_item_url(username))",
            [],
            false
          ],
          [
            565,
            "",
            "",
            [],
            565,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            566,
            "",
            "",
            [],
            566,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;username&#39;], user.username)",
            [],
            false
          ],
          [
            567,
            "",
            "",
            [],
            567,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;first_name&#39;], user.first_name)",
            [],
            false
          ],
          [
            568,
            "",
            "",
            [],
            568,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;last_name&#39;], user.last_name)",
            [],
            false
          ],
          [
            569,
            "",
            "",
            [],
            569,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;id&#39;], user.id)",
            [],
            false
          ],
          [
            570,
            "",
            "",
            [],
            570,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;email&#39;], user.email)",
            [],
            false
          ],
          [
            571,
            "",
            "",
            [],
            571,
            "",
            [],
            false
          ],
          [
            572,
            "",
            "",
            [],
            572,
            "    def test_get_user_with_site(self):",
            [],
            false
          ],
          [
            573,
            "",
            "",
            [],
            573,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            574,
            "",
            "",
            [],
            574,
            "        self.client.logout()",
            [],
            false
          ],
          [
            575,
            "",
            "",
            [],
            575,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            576,
            "",
            "",
            [],
            576,
            "",
            [],
            false
          ],
          [
            577,
            "",
            "",
            [],
            577,
            "        username = &#39;doc&#39;",
            [],
            false
          ],
          [
            578,
            "",
            "",
            [],
            578,
            "        user = User.objects.get(username=username)",
            [],
            false
          ],
          [
            579,
            "",
            "",
            [],
            579,
            "",
            [],
            false
          ],
          [
            580,
            "",
            "",
            [],
            580,
            "        rsp = self.apiGet(self.get_item_url(username, self.local_site_name))",
            [],
            false
          ],
          [
            581,
            "",
            "",
            [],
            581,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            582,
            "",
            "",
            [],
            582,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;username&#39;], user.username)",
            [],
            false
          ],
          [
            583,
            "",
            "",
            [],
            583,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;first_name&#39;], user.first_name)",
            [],
            false
          ],
          [
            584,
            "",
            "",
            [],
            584,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;last_name&#39;], user.last_name)",
            [],
            false
          ],
          [
            585,
            "",
            "",
            [],
            585,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;id&#39;], user.id)",
            [],
            false
          ],
          [
            586,
            "",
            "",
            [],
            586,
            "        self.assertEqual(rsp[&#39;user&#39;][&#39;email&#39;], user.email)",
            [],
            false
          ],
          [
            587,
            "",
            "",
            [],
            587,
            "",
            [],
            false
          ],
          [
            588,
            "",
            "",
            [],
            588,
            "    def test_get_missing_user_with_site(self):",
            [],
            false
          ],
          [
            589,
            "",
            "",
            [],
            589,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            590,
            "",
            "",
            [],
            590,
            "        self.client.logout()",
            [],
            false
          ],
          [
            591,
            "",
            "",
            [],
            591,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            592,
            "",
            "",
            [],
            592,
            "",
            [],
            false
          ],
          [
            593,
            "",
            "",
            [],
            593,
            "        rsp = self.apiGet(self.get_item_url(&#39;dopey&#39;, self.local_site_name),",
            [],
            false
          ],
          [
            594,
            "",
            "",
            [],
            594,
            "                          expected_status=404)",
            [],
            false
          ],
          [
            595,
            "",
            "",
            [],
            595,
            "",
            [],
            false
          ],
          [
            596,
            "",
            "",
            [],
            596,
            "    def test_get_user_with_site_no_access(self):",
            [],
            false
          ],
          [
            597,
            "",
            "",
            [],
            597,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/ API with a local site and Permission Denied error.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            598,
            "",
            "",
            [],
            598,
            "        self.apiGet(self.get_item_url(&#39;doc&#39;, self.local_site_name),",
            [],
            false
          ],
          [
            599,
            "",
            "",
            [],
            599,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            600,
            "",
            "",
            [],
            600,
            "",
            [],
            false
          ],
          [
            601,
            "",
            "",
            [],
            601,
            "    def get_list_url(self, local_site_name=None):",
            [],
            false
          ],
          [
            602,
            "",
            "",
            [],
            602,
            "        return local_site_reverse(&#39;users-resource&#39;,",
            [],
            false
          ],
          [
            603,
            "",
            "",
            [],
            603,
            "                                  local_site_name=local_site_name)",
            [],
            false
          ],
          [
            604,
            "",
            "",
            [],
            604,
            "",
            [],
            false
          ],
          [
            605,
            "",
            "",
            [],
            605,
            "    @classmethod",
            [],
            false
          ],
          [
            606,
            "",
            "",
            [],
            606,
            "    def get_item_url(cls, username, local_site_name=None):",
            [],
            false
          ],
          [
            607,
            "",
            "",
            [],
            607,
            "        return local_site_reverse(&#39;user-resource&#39;,",
            [],
            false
          ],
          [
            608,
            "",
            "",
            [],
            608,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            609,
            "",
            "",
            [],
            609,
            "                                  kwargs={",
            [],
            false
          ],
          [
            610,
            "",
            "",
            [],
            610,
            "                                      &#39;username&#39;: username,",
            [],
            false
          ],
          [
            611,
            "",
            "",
            [],
            611,
            "                                  })",
            [],
            false
          ],
          [
            612,
            "",
            "",
            [],
            612,
            "",
            [],
            false
          ],
          [
            613,
            "",
            "",
            [],
            613,
            "",
            [],
            false
          ],
          [
            614,
            "",
            "",
            [],
            614,
            "class WatchedReviewRequestResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            615,
            "",
            "",
            [],
            615,
            "    &quot;&quot;&quot;Testing the WatchedReviewRequestResource API tests.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            616,
            "",
            "",
            [],
            616,
            "",
            [],
            false
          ],
          [
            617,
            "",
            "",
            [],
            617,
            "    def test_post_watched_review_request(self):",
            [],
            false
          ],
          [
            618,
            "",
            "",
            [],
            618,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review_request/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            619,
            "",
            "",
            [],
            619,
            "        review_request = ReviewRequest.objects.public()[0]",
            [],
            false
          ],
          [
            620,
            "",
            "",
            [],
            620,
            "        rsp = self.apiPost(self.get_list_url(self.user.username), {",
            [],
            false
          ],
          [
            621,
            "",
            "",
            [],
            621,
            "            &#39;object_id&#39;: review_request.display_id,",
            [],
            false
          ],
          [
            622,
            "",
            "",
            [],
            622,
            "        })",
            [],
            false
          ],
          [
            623,
            "",
            "",
            [],
            623,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            624,
            "",
            "",
            [],
            624,
            "        self.assert_(review_request in",
            [],
            false
          ],
          [
            625,
            "",
            "",
            [],
            625,
            "                     self.user.get_profile().starred_review_requests.all())",
            [],
            false
          ],
          [
            626,
            "",
            "",
            [],
            626,
            "",
            [],
            false
          ],
          [
            627,
            "",
            "",
            [],
            627,
            "    def test_post_watched_review_request_with_does_not_exist_error(self):",
            [],
            false
          ],
          [
            628,
            "",
            "",
            [],
            628,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review_request/ with Does Not Exist error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            629,
            "",
            "",
            [],
            629,
            "        rsp = self.apiPost(self.get_list_url(self.user.username), {",
            [],
            false
          ],
          [
            630,
            "",
            "",
            [],
            630,
            "            &#39;object_id&#39;: 999,",
            [],
            false
          ],
          [
            631,
            "",
            "",
            [],
            631,
            "        }, expected_status=404)",
            [],
            false
          ],
          [
            632,
            "",
            "",
            [],
            632,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            633,
            "",
            "",
            [],
            633,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], DOES_NOT_EXIST.code)",
            [],
            false
          ],
          [
            634,
            "",
            "",
            [],
            634,
            "",
            [],
            false
          ],
          [
            635,
            "",
            "",
            [],
            635,
            "    def test_post_watched_review_request_with_site(self):",
            [],
            false
          ],
          [
            636,
            "",
            "",
            [],
            636,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review_request/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            637,
            "",
            "",
            [],
            637,
            "        username = &#39;doc&#39;",
            [],
            false
          ],
          [
            638,
            "",
            "",
            [],
            638,
            "        user = User.objects.get(username=username)",
            [],
            false
          ],
          [
            639,
            "",
            "",
            [],
            639,
            "",
            [],
            false
          ],
          [
            640,
            "",
            "",
            [],
            640,
            "        self.client.logout()",
            [],
            false
          ],
          [
            641,
            "",
            "",
            [],
            641,
            "        self.client.login(username=username, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            642,
            "",
            "",
            [],
            642,
            "",
            [],
            false
          ],
          [
            643,
            "",
            "",
            [],
            643,
            "        local_site = LocalSite.objects.get(name=self.local_site_name)",
            [],
            false
          ],
          [
            644,
            "",
            "",
            [],
            644,
            "        review_request = ReviewRequest.objects.public(local_site=local_site)[0]",
            [],
            false
          ],
          [
            645,
            "",
            "",
            [],
            645,
            "",
            [],
            false
          ],
          [
            646,
            "",
            "",
            [],
            646,
            "        rsp = self.apiPost(self.get_list_url(username, self.local_site_name),",
            [],
            false
          ],
          [
            647,
            "",
            "",
            [],
            647,
            "                           { &#39;object_id&#39;: review_request.display_id, })",
            [],
            false
          ],
          [
            648,
            "",
            "",
            [],
            648,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            649,
            "",
            "",
            [],
            649,
            "        self.assertTrue(review_request in",
            [],
            false
          ],
          [
            650,
            "",
            "",
            [],
            650,
            "                        user.get_profile().starred_review_requests.all())",
            [],
            false
          ],
          [
            651,
            "",
            "",
            [],
            651,
            "",
            [],
            false
          ],
          [
            652,
            "",
            "",
            [],
            652,
            "    def test_post_watched_review_request_with_site_does_not_exist_error(self):",
            [],
            false
          ],
          [
            653,
            "",
            "",
            [],
            653,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review_request/ API with a local site and Does Not Exist error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            654,
            "",
            "",
            [],
            654,
            "        self.client.logout()",
            [],
            false
          ],
          [
            655,
            "",
            "",
            [],
            655,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            656,
            "",
            "",
            [],
            656,
            "",
            [],
            false
          ],
          [
            657,
            "",
            "",
            [],
            657,
            "        rsp = self.apiPost(self.get_list_url(&#39;doc&#39;, self.local_site_name),",
            [],
            false
          ],
          [
            658,
            "",
            "",
            [],
            658,
            "                           { &#39;object_id&#39;: 10, },",
            [],
            false
          ],
          [
            659,
            "",
            "",
            [],
            659,
            "                           expected_status=404)",
            [],
            false
          ],
          [
            660,
            "",
            "",
            [],
            660,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            661,
            "",
            "",
            [],
            661,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], DOES_NOT_EXIST.code)",
            [],
            false
          ],
          [
            662,
            "",
            "",
            [],
            662,
            "",
            [],
            false
          ],
          [
            663,
            "",
            "",
            [],
            663,
            "    def test_post_watched_review_request_with_site_no_access(self):",
            [],
            false
          ],
          [
            664,
            "",
            "",
            [],
            664,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review_request/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            665,
            "",
            "",
            [],
            665,
            "        rsp = self.apiPost(self.get_list_url(&#39;doc&#39;, self.local_site_name),",
            [],
            false
          ],
          [
            666,
            "",
            "",
            [],
            666,
            "                           { &#39;object_id&#39;: 10, },",
            [],
            false
          ],
          [
            667,
            "",
            "",
            [],
            667,
            "                           expected_status=403)",
            [],
            false
          ],
          [
            668,
            "",
            "",
            [],
            668,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            669,
            "",
            "",
            [],
            669,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], PERMISSION_DENIED.code)",
            [],
            false
          ],
          [
            670,
            "",
            "",
            [],
            670,
            "",
            [],
            false
          ],
          [
            671,
            "",
            "",
            [],
            671,
            "    def test_delete_watched_review_request(self):",
            [],
            false
          ],
          [
            672,
            "",
            "",
            [],
            672,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review_request/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            673,
            "",
            "",
            [],
            673,
            "        # First, star it.",
            [],
            false
          ],
          [
            674,
            "",
            "",
            [],
            674,
            "        self.test_post_watched_review_request()",
            [],
            false
          ],
          [
            675,
            "",
            "",
            [],
            675,
            "",
            [],
            false
          ],
          [
            676,
            "",
            "",
            [],
            676,
            "        review_request = ReviewRequest.objects.public()[0]",
            [],
            false
          ],
          [
            677,
            "",
            "",
            [],
            677,
            "        self.apiDelete(self.get_item_url(self.user.username,",
            [],
            false
          ],
          [
            678,
            "",
            "",
            [],
            678,
            "                                          review_request.display_id))",
            [],
            false
          ],
          [
            679,
            "",
            "",
            [],
            679,
            "        self.assertTrue(review_request not in",
            [],
            false
          ],
          [
            680,
            "",
            "",
            [],
            680,
            "                        self.user.get_profile().starred_review_requests.all())",
            [],
            false
          ],
          [
            681,
            "",
            "",
            [],
            681,
            "",
            [],
            false
          ],
          [
            682,
            "",
            "",
            [],
            682,
            "    def test_delete_watched_review_request_with_does_not_exist_error(self):",
            [],
            false
          ],
          [
            683,
            "",
            "",
            [],
            683,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review_request/ API with Does Not Exist error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            684,
            "",
            "",
            [],
            684,
            "        rsp = self.apiDelete(self.get_item_url(self.user.username, 999),",
            [],
            false
          ],
          [
            685,
            "",
            "",
            [],
            685,
            "                             expected_status=404)",
            [],
            false
          ],
          [
            686,
            "",
            "",
            [],
            686,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            687,
            "",
            "",
            [],
            687,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], DOES_NOT_EXIST.code)",
            [],
            false
          ],
          [
            688,
            "",
            "",
            [],
            688,
            "",
            [],
            false
          ],
          [
            689,
            "",
            "",
            [],
            689,
            "    def test_delete_watched_review_request_with_site(self):",
            [],
            false
          ],
          [
            690,
            "",
            "",
            [],
            690,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review_request/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            691,
            "",
            "",
            [],
            691,
            "        self.test_post_watched_review_request_with_site()",
            [],
            false
          ],
          [
            692,
            "",
            "",
            [],
            692,
            "",
            [],
            false
          ],
          [
            693,
            "",
            "",
            [],
            693,
            "        user = User.objects.get(username=&#39;doc&#39;)",
            [],
            false
          ],
          [
            694,
            "",
            "",
            [],
            694,
            "        review_request = ReviewRequest.objects.get(",
            [],
            false
          ],
          [
            695,
            "",
            "",
            [],
            695,
            "            local_id=1, local_site__name=self.local_site_name)",
            [],
            false
          ],
          [
            696,
            "",
            "",
            [],
            696,
            "",
            [],
            false
          ],
          [
            697,
            "",
            "",
            [],
            697,
            "        self.apiDelete(self.get_item_url(user.username,",
            [],
            false
          ],
          [
            698,
            "",
            "",
            [],
            698,
            "                                          review_request.display_id,",
            [],
            false
          ],
          [
            699,
            "",
            "",
            [],
            699,
            "                                          self.local_site_name))",
            [],
            false
          ],
          [
            700,
            "",
            "",
            [],
            700,
            "        self.assertTrue(review_request not in",
            [],
            false
          ],
          [
            701,
            "",
            "",
            [],
            701,
            "                        user.get_profile().starred_review_requests.all())",
            [],
            false
          ],
          [
            702,
            "",
            "",
            [],
            702,
            "",
            [],
            false
          ],
          [
            703,
            "",
            "",
            [],
            703,
            "    def test_delete_watched_review_request_with_site_no_access(self):",
            [],
            false
          ],
          [
            704,
            "",
            "",
            [],
            704,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review_request/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            705,
            "",
            "",
            [],
            705,
            "        rsp = self.apiDelete(self.get_item_url(self.user.username, 1,",
            [],
            false
          ],
          [
            706,
            "",
            "",
            [],
            706,
            "                                                self.local_site_name),",
            [],
            false
          ],
          [
            707,
            "",
            "",
            [],
            707,
            "                             expected_status=403)",
            [],
            false
          ],
          [
            708,
            "",
            "",
            [],
            708,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            709,
            "",
            "",
            [],
            709,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], PERMISSION_DENIED.code)",
            [],
            false
          ],
          [
            710,
            "",
            "",
            [],
            710,
            "",
            [],
            false
          ],
          [
            711,
            "",
            "",
            [],
            711,
            "    def test_get_watched_review_requests(self):",
            [],
            false
          ],
          [
            712,
            "",
            "",
            [],
            712,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/watched/review_request/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            713,
            "",
            "",
            [],
            713,
            "        self.test_post_watched_review_request()",
            [],
            false
          ],
          [
            714,
            "",
            "",
            [],
            714,
            "",
            [],
            false
          ],
          [
            715,
            "",
            "",
            [],
            715,
            "        rsp = self.apiGet(self.get_list_url(self.user.username))",
            [],
            false
          ],
          [
            716,
            "",
            "",
            [],
            716,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            717,
            "",
            "",
            [],
            717,
            "",
            [],
            false
          ],
          [
            718,
            "",
            "",
            [],
            718,
            "        watched = self.user.get_profile().starred_review_requests.all()",
            [],
            false
          ],
          [
            719,
            "",
            "",
            [],
            719,
            "        apiwatched = rsp[&#39;watched_review_requests&#39;]",
            [],
            false
          ],
          [
            720,
            "",
            "",
            [],
            720,
            "",
            [],
            false
          ],
          [
            721,
            "",
            "",
            [],
            721,
            "        self.assertEqual(len(watched), len(apiwatched))",
            [],
            false
          ],
          [
            722,
            "",
            "",
            [],
            722,
            "        for i in range(len(watched)):",
            [],
            false
          ],
          [
            723,
            "",
            "",
            [],
            723,
            "            self.assertEqual(watched[i].id,",
            [],
            false
          ],
          [
            724,
            "",
            "",
            [],
            724,
            "                             apiwatched[i][&#39;watched_review_request&#39;][&#39;id&#39;])",
            [],
            false
          ],
          [
            725,
            "",
            "",
            [],
            725,
            "            self.assertEqual(watched[i].summary,",
            [],
            false
          ],
          [
            726,
            "",
            "",
            [],
            726,
            "                             apiwatched[i][&#39;watched_review_request&#39;][&#39;summary&#39;])",
            [],
            false
          ],
          [
            727,
            "",
            "",
            [],
            727,
            "",
            [],
            false
          ],
          [
            728,
            "",
            "",
            [],
            728,
            "    def test_get_watched_review_requests_with_site(self):",
            [],
            false
          ],
          [
            729,
            "",
            "",
            [],
            729,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/watched/review_request/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            730,
            "",
            "",
            [],
            730,
            "        username = &#39;doc&#39;",
            [],
            false
          ],
          [
            731,
            "",
            "",
            [],
            731,
            "        user = User.objects.get(username=username)",
            [],
            false
          ],
          [
            732,
            "",
            "",
            [],
            732,
            "",
            [],
            false
          ],
          [
            733,
            "",
            "",
            [],
            733,
            "        self.test_post_watched_review_request_with_site()",
            [],
            false
          ],
          [
            734,
            "",
            "",
            [],
            734,
            "",
            [],
            false
          ],
          [
            735,
            "",
            "",
            [],
            735,
            "        rsp = self.apiGet(self.get_list_url(username, self.local_site_name))",
            [],
            false
          ],
          [
            736,
            "",
            "",
            [],
            736,
            "",
            [],
            false
          ],
          [
            737,
            "",
            "",
            [],
            737,
            "        watched = user.get_profile().starred_review_requests.filter(",
            [],
            false
          ],
          [
            738,
            "",
            "",
            [],
            738,
            "            local_site__name=self.local_site_name)",
            [],
            false
          ],
          [
            739,
            "",
            "",
            [],
            739,
            "        apiwatched = rsp[&#39;watched_review_requests&#39;]",
            [],
            false
          ],
          [
            740,
            "",
            "",
            [],
            740,
            "",
            [],
            false
          ],
          [
            741,
            "",
            "",
            [],
            741,
            "        self.assertEqual(len(watched), len(apiwatched))",
            [],
            false
          ],
          [
            742,
            "",
            "",
            [],
            742,
            "        for i in range(len(watched)):",
            [],
            false
          ],
          [
            743,
            "",
            "",
            [],
            743,
            "            self.assertEqual(watched[i].display_id,",
            [],
            false
          ],
          [
            744,
            "",
            "",
            [],
            744,
            "                             apiwatched[i][&#39;watched_review_request&#39;][&#39;id&#39;])",
            [],
            false
          ],
          [
            745,
            "",
            "",
            [],
            745,
            "            self.assertEqual(watched[i].summary,",
            [],
            false
          ],
          [
            746,
            "",
            "",
            [],
            746,
            "                             apiwatched[i][&#39;watched_review_request&#39;][&#39;summary&#39;])",
            [],
            false
          ],
          [
            747,
            "",
            "",
            [],
            747,
            "",
            [],
            false
          ],
          [
            748,
            "",
            "",
            [],
            748,
            "    def test_get_watched_review_requests_with_site_no_access(self):",
            [],
            false
          ],
          [
            749,
            "",
            "",
            [],
            749,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/watched/review_request/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            750,
            "",
            "",
            [],
            750,
            "        rsp = self.apiGet(self.get_list_url(self.user.username,",
            [],
            false
          ],
          [
            751,
            "",
            "",
            [],
            751,
            "                                             self.local_site_name),",
            [],
            false
          ],
          [
            752,
            "",
            "",
            [],
            752,
            "                          expected_status=403)",
            [],
            false
          ],
          [
            753,
            "",
            "",
            [],
            753,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            754,
            "",
            "",
            [],
            754,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], PERMISSION_DENIED.code)",
            [],
            false
          ],
          [
            755,
            "",
            "",
            [],
            755,
            "",
            [],
            false
          ],
          [
            756,
            "",
            "",
            [],
            756,
            "    def test_get_watched_review_requests_with_site_does_not_exist(self):",
            [],
            false
          ],
          [
            757,
            "",
            "",
            [],
            757,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/watched/review_request/ API with a local site and Does Not Exist error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            758,
            "",
            "",
            [],
            758,
            "        self.client.logout()",
            [],
            false
          ],
          [
            759,
            "",
            "",
            [],
            759,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            760,
            "",
            "",
            [],
            760,
            "",
            [],
            false
          ],
          [
            761,
            "",
            "",
            [],
            761,
            "        rsp = self.apiGet(self.get_list_url(self.user.username,",
            [],
            false
          ],
          [
            762,
            "",
            "",
            [],
            762,
            "                                             self.local_site_name),",
            [],
            false
          ],
          [
            763,
            "",
            "",
            [],
            763,
            "                          expected_status=404)",
            [],
            false
          ],
          [
            764,
            "",
            "",
            [],
            764,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            765,
            "",
            "",
            [],
            765,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], DOES_NOT_EXIST.code)",
            [],
            false
          ],
          [
            766,
            "",
            "",
            [],
            766,
            "",
            [],
            false
          ],
          [
            767,
            "",
            "",
            [],
            767,
            "    def get_list_url(self, username, local_site_name=None):",
            [],
            false
          ],
          [
            768,
            "",
            "",
            [],
            768,
            "        return local_site_reverse(&#39;watched-review-requests-resource&#39;,",
            [],
            false
          ],
          [
            769,
            "",
            "",
            [],
            769,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            770,
            "",
            "",
            [],
            770,
            "                                  kwargs={",
            [],
            false
          ],
          [
            771,
            "",
            "",
            [],
            771,
            "                                      &#39;username&#39;: username,",
            [],
            false
          ],
          [
            772,
            "",
            "",
            [],
            772,
            "                                  })",
            [],
            false
          ],
          [
            773,
            "",
            "",
            [],
            773,
            "",
            [],
            false
          ],
          [
            774,
            "",
            "",
            [],
            774,
            "    def get_item_url(self, username, object_id, local_site_name=None):",
            [],
            false
          ],
          [
            775,
            "",
            "",
            [],
            775,
            "        return local_site_reverse(&#39;watched-review-request-resource&#39;,",
            [],
            false
          ],
          [
            776,
            "",
            "",
            [],
            776,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            777,
            "",
            "",
            [],
            777,
            "                                  kwargs={",
            [],
            false
          ],
          [
            778,
            "",
            "",
            [],
            778,
            "                                      &#39;username&#39;: username,",
            [],
            false
          ],
          [
            779,
            "",
            "",
            [],
            779,
            "                                      &#39;watched_obj_id&#39;: object_id,",
            [],
            false
          ],
          [
            780,
            "",
            "",
            [],
            780,
            "                                  })",
            [],
            false
          ],
          [
            781,
            "",
            "",
            [],
            781,
            "",
            [],
            false
          ],
          [
            782,
            "",
            "",
            [],
            782,
            "",
            [],
            false
          ],
          [
            783,
            "",
            "",
            [],
            783,
            "class WatchedReviewGroupResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            784,
            "",
            "",
            [],
            784,
            "    &quot;&quot;&quot;Testing the WatchedReviewGroupResource API tests.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            785,
            "",
            "",
            [],
            785,
            "",
            [],
            false
          ],
          [
            786,
            "",
            "",
            [],
            786,
            "    def test_post_watched_review_group(self):",
            [],
            false
          ],
          [
            787,
            "",
            "",
            [],
            787,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review-groups/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            788,
            "",
            "",
            [],
            788,
            "        group = Group.objects.get(name=&#39;devgroup&#39;, local_site=None)",
            [],
            false
          ],
          [
            789,
            "",
            "",
            [],
            789,
            "",
            [],
            false
          ],
          [
            790,
            "",
            "",
            [],
            790,
            "        rsp = self.apiPost(self.get_list_url(self.user.username), {",
            [],
            false
          ],
          [
            791,
            "",
            "",
            [],
            791,
            "            &#39;object_id&#39;: group.name,",
            [],
            false
          ],
          [
            792,
            "",
            "",
            [],
            792,
            "        })",
            [],
            false
          ],
          [
            793,
            "",
            "",
            [],
            793,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            794,
            "",
            "",
            [],
            794,
            "        self.assert_(group in self.user.get_profile().starred_groups.all())",
            [],
            false
          ],
          [
            795,
            "",
            "",
            [],
            795,
            "",
            [],
            false
          ],
          [
            796,
            "",
            "",
            [],
            796,
            "    def test_post_watched_review_group_with_does_not_exist_error(self):",
            [],
            false
          ],
          [
            797,
            "",
            "",
            [],
            797,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review-groups/ API with Does Not Exist error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            798,
            "",
            "",
            [],
            798,
            "        rsp = self.apiPost(self.get_list_url(self.user.username), {",
            [],
            false
          ],
          [
            799,
            "",
            "",
            [],
            799,
            "            &#39;object_id&#39;: &#39;invalidgroup&#39;,",
            [],
            false
          ],
          [
            800,
            "",
            "",
            [],
            800,
            "        }, expected_status=404)",
            [],
            false
          ],
          [
            801,
            "",
            "",
            [],
            801,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            802,
            "",
            "",
            [],
            802,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], DOES_NOT_EXIST.code)",
            [],
            false
          ],
          [
            803,
            "",
            "",
            [],
            803,
            "",
            [],
            false
          ],
          [
            804,
            "",
            "",
            [],
            804,
            "    def test_post_watched_review_group_with_site(self):",
            [],
            false
          ],
          [
            805,
            "",
            "",
            [],
            805,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review-groups/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            806,
            "",
            "",
            [],
            806,
            "        username = &#39;doc&#39;",
            [],
            false
          ],
          [
            807,
            "",
            "",
            [],
            807,
            "        user = User.objects.get(username=username)",
            [],
            false
          ],
          [
            808,
            "",
            "",
            [],
            808,
            "",
            [],
            false
          ],
          [
            809,
            "",
            "",
            [],
            809,
            "        self.client.logout()",
            [],
            false
          ],
          [
            810,
            "",
            "",
            [],
            810,
            "        self.client.login(username=username, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            811,
            "",
            "",
            [],
            811,
            "",
            [],
            false
          ],
          [
            812,
            "",
            "",
            [],
            812,
            "        group = Group.objects.get(name=&#39;sitegroup&#39;,",
            [],
            false
          ],
          [
            813,
            "",
            "",
            [],
            813,
            "                                  local_site__name=self.local_site_name)",
            [],
            false
          ],
          [
            814,
            "",
            "",
            [],
            814,
            "",
            [],
            false
          ],
          [
            815,
            "",
            "",
            [],
            815,
            "        rsp = self.apiPost(self.get_list_url(username, self.local_site_name),",
            [],
            false
          ],
          [
            816,
            "",
            "",
            [],
            816,
            "                           { &#39;object_id&#39;: group.name, })",
            [],
            false
          ],
          [
            817,
            "",
            "",
            [],
            817,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            818,
            "",
            "",
            [],
            818,
            "        self.assertTrue(group in user.get_profile().starred_groups.all())",
            [],
            false
          ],
          [
            819,
            "",
            "",
            [],
            819,
            "",
            [],
            false
          ],
          [
            820,
            "",
            "",
            [],
            820,
            "    def test_post_watched_review_group_with_site_does_not_exist_error(self):",
            [],
            false
          ],
          [
            821,
            "",
            "",
            [],
            821,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review-groups/ API with a local site and Does Not Exist error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            822,
            "",
            "",
            [],
            822,
            "        username = &#39;doc&#39;",
            [],
            false
          ],
          [
            823,
            "",
            "",
            [],
            823,
            "",
            [],
            false
          ],
          [
            824,
            "",
            "",
            [],
            824,
            "        self.client.logout()",
            [],
            false
          ],
          [
            825,
            "",
            "",
            [],
            825,
            "        self.client.login(username=username, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            826,
            "",
            "",
            [],
            826,
            "",
            [],
            false
          ],
          [
            827,
            "",
            "",
            [],
            827,
            "        rsp = self.apiPost(self.get_list_url(username, self.local_site_name),",
            [],
            false
          ],
          [
            828,
            "",
            "",
            [],
            828,
            "                           { &#39;object_id&#39;: &#39;devgroup&#39;, },",
            [],
            false
          ],
          [
            829,
            "",
            "",
            [],
            829,
            "                           expected_status=404)",
            [],
            false
          ],
          [
            830,
            "",
            "",
            [],
            830,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            831,
            "",
            "",
            [],
            831,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], DOES_NOT_EXIST.code)",
            [],
            false
          ],
          [
            832,
            "",
            "",
            [],
            832,
            "",
            [],
            false
          ],
          [
            833,
            "",
            "",
            [],
            833,
            "    def test_post_watched_review_group_with_site_no_access(self):",
            [],
            false
          ],
          [
            834,
            "",
            "",
            [],
            834,
            "        &quot;&quot;&quot;Testing the POST users/&lt;username&gt;/watched/review-groups/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            835,
            "",
            "",
            [],
            835,
            "        rsp = self.apiPost(self.get_list_url(self.user.username,",
            [],
            false
          ],
          [
            836,
            "",
            "",
            [],
            836,
            "                                              self.local_site_name),",
            [],
            false
          ],
          [
            837,
            "",
            "",
            [],
            837,
            "                           { &#39;object_id&#39;: &#39;devgroup&#39;, },",
            [],
            false
          ],
          [
            838,
            "",
            "",
            [],
            838,
            "                           expected_status=403)",
            [],
            false
          ],
          [
            839,
            "",
            "",
            [],
            839,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            840,
            "",
            "",
            [],
            840,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], PERMISSION_DENIED.code)",
            [],
            false
          ],
          [
            841,
            "",
            "",
            [],
            841,
            "",
            [],
            false
          ],
          [
            842,
            "",
            "",
            [],
            842,
            "",
            [],
            false
          ],
          [
            843,
            "",
            "",
            [],
            843,
            "    def test_delete_watched_review_group(self):",
            [],
            false
          ],
          [
            844,
            "",
            "",
            [],
            844,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review-groups/&lt;id&gt;/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            845,
            "",
            "",
            [],
            845,
            "        # First, star it.",
            [],
            false
          ],
          [
            846,
            "",
            "",
            [],
            846,
            "        self.test_post_watched_review_group()",
            [],
            false
          ],
          [
            847,
            "",
            "",
            [],
            847,
            "",
            [],
            false
          ],
          [
            848,
            "",
            "",
            [],
            848,
            "        group = Group.objects.get(name=&#39;devgroup&#39;, local_site=None)",
            [],
            false
          ],
          [
            849,
            "",
            "",
            [],
            849,
            "",
            [],
            false
          ],
          [
            850,
            "",
            "",
            [],
            850,
            "        self.apiDelete(self.get_item_url(self.user.username, group.name))",
            [],
            false
          ],
          [
            851,
            "",
            "",
            [],
            851,
            "        self.assertFalse(group in",
            [],
            false
          ],
          [
            852,
            "",
            "",
            [],
            852,
            "                         self.user.get_profile().starred_groups.all())",
            [],
            false
          ],
          [
            853,
            "",
            "",
            [],
            853,
            "",
            [],
            false
          ],
          [
            854,
            "",
            "",
            [],
            854,
            "    def test_delete_watched_review_group_with_does_not_exist_error(self):",
            [],
            false
          ],
          [
            855,
            "",
            "",
            [],
            855,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review-groups/&lt;id&gt;/ API with Does Not Exist error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            856,
            "",
            "",
            [],
            856,
            "        rsp = self.apiDelete(self.get_item_url(self.user.username,",
            [],
            false
          ],
          [
            857,
            "",
            "",
            [],
            857,
            "                                                &#39;invalidgroup&#39;),",
            [],
            false
          ],
          [
            858,
            "",
            "",
            [],
            858,
            "                             expected_status=404)",
            [],
            false
          ],
          [
            859,
            "",
            "",
            [],
            859,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            860,
            "",
            "",
            [],
            860,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], DOES_NOT_EXIST.code)",
            [],
            false
          ],
          [
            861,
            "",
            "",
            [],
            861,
            "",
            [],
            false
          ],
          [
            862,
            "",
            "",
            [],
            862,
            "    def test_delete_watched_review_group_with_site(self):",
            [],
            false
          ],
          [
            863,
            "",
            "",
            [],
            863,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review-groups/&lt;id&gt;/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            864,
            "",
            "",
            [],
            864,
            "        self.test_post_watched_review_group_with_site()",
            [],
            false
          ],
          [
            865,
            "",
            "",
            [],
            865,
            "",
            [],
            false
          ],
          [
            866,
            "",
            "",
            [],
            866,
            "        user = User.objects.get(username=&#39;doc&#39;)",
            [],
            false
          ],
          [
            867,
            "",
            "",
            [],
            867,
            "        group = Group.objects.get(name=&#39;sitegroup&#39;,",
            [],
            false
          ],
          [
            868,
            "",
            "",
            [],
            868,
            "                                  local_site__name=self.local_site_name)",
            [],
            false
          ],
          [
            869,
            "",
            "",
            [],
            869,
            "",
            [],
            false
          ],
          [
            870,
            "",
            "",
            [],
            870,
            "        self.apiDelete(self.get_item_url(user.username, group.name,",
            [],
            false
          ],
          [
            871,
            "",
            "",
            [],
            871,
            "                                          self.local_site_name))",
            [],
            false
          ],
          [
            872,
            "",
            "",
            [],
            872,
            "        self.assertFalse(group in user.get_profile().starred_groups.all())",
            [],
            false
          ],
          [
            873,
            "",
            "",
            [],
            873,
            "",
            [],
            false
          ],
          [
            874,
            "",
            "",
            [],
            874,
            "    def test_delete_watched_review_group_with_site_no_access(self):",
            [],
            false
          ],
          [
            875,
            "",
            "",
            [],
            875,
            "        &quot;&quot;&quot;Testing the DELETE users/&lt;username&gt;/watched/review-groups/&lt;id&gt;/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            876,
            "",
            "",
            [],
            876,
            "        rsp = self.apiDelete(self.get_item_url(self.user.username, &#39;group&#39;,",
            [],
            false
          ],
          [
            877,
            "",
            "",
            [],
            877,
            "                                                self.local_site_name),",
            [],
            false
          ],
          [
            878,
            "",
            "",
            [],
            878,
            "                             expected_status=403)",
            [],
            false
          ],
          [
            879,
            "",
            "",
            [],
            879,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            880,
            "",
            "",
            [],
            880,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], PERMISSION_DENIED.code)",
            [],
            false
          ],
          [
            881,
            "",
            "",
            [],
            881,
            "",
            [],
            false
          ],
          [
            882,
            "",
            "",
            [],
            882,
            "    def test_get_watched_review_groups(self):",
            [],
            false
          ],
          [
            883,
            "",
            "",
            [],
            883,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/watched/review-groups/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            884,
            "",
            "",
            [],
            884,
            "        self.test_post_watched_review_group()",
            [],
            false
          ],
          [
            885,
            "",
            "",
            [],
            885,
            "",
            [],
            false
          ],
          [
            886,
            "",
            "",
            [],
            886,
            "        rsp = self.apiGet(self.get_list_url(self.user.username))",
            [],
            false
          ],
          [
            887,
            "",
            "",
            [],
            887,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            888,
            "",
            "",
            [],
            888,
            "",
            [],
            false
          ],
          [
            889,
            "",
            "",
            [],
            889,
            "        watched = self.user.get_profile().starred_groups.all()",
            [],
            false
          ],
          [
            890,
            "",
            "",
            [],
            890,
            "        apigroups = rsp[&#39;watched_review_groups&#39;]",
            [],
            false
          ],
          [
            891,
            "",
            "",
            [],
            891,
            "",
            [],
            false
          ],
          [
            892,
            "",
            "",
            [],
            892,
            "        self.assertEqual(len(apigroups), len(watched))",
            [],
            false
          ],
          [
            893,
            "",
            "",
            [],
            893,
            "",
            [],
            false
          ],
          [
            894,
            "",
            "",
            [],
            894,
            "        for id in range(len(watched)):",
            [],
            false
          ],
          [
            895,
            "",
            "",
            [],
            895,
            "            self.assertEqual(apigroups[id][&#39;watched_review_group&#39;][&#39;name&#39;],",
            [],
            false
          ],
          [
            896,
            "",
            "",
            [],
            896,
            "                             watched[id].name)",
            [],
            false
          ],
          [
            897,
            "",
            "",
            [],
            897,
            "",
            [],
            false
          ],
          [
            898,
            "",
            "",
            [],
            898,
            "    def test_get_watched_review_groups_with_site(self):",
            [],
            false
          ],
          [
            899,
            "",
            "",
            [],
            899,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/watched/review-groups/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            900,
            "",
            "",
            [],
            900,
            "        self.test_post_watched_review_group_with_site()",
            [],
            false
          ],
          [
            901,
            "",
            "",
            [],
            901,
            "",
            [],
            false
          ],
          [
            902,
            "",
            "",
            [],
            902,
            "        rsp = self.apiGet(self.get_list_url(&#39;doc&#39;, self.local_site_name))",
            [],
            false
          ],
          [
            903,
            "",
            "",
            [],
            903,
            "",
            [],
            false
          ],
          [
            904,
            "",
            "",
            [],
            904,
            "        watched = self.user.get_profile().starred_groups.filter(",
            [],
            false
          ],
          [
            905,
            "",
            "",
            [],
            905,
            "            local_site__name=self.local_site_name)",
            [],
            false
          ],
          [
            906,
            "",
            "",
            [],
            906,
            "        apigroups = rsp[&#39;watched_review_groups&#39;]",
            [],
            false
          ],
          [
            907,
            "",
            "",
            [],
            907,
            "",
            [],
            false
          ],
          [
            908,
            "",
            "",
            [],
            908,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            909,
            "",
            "",
            [],
            909,
            "",
            [],
            false
          ],
          [
            910,
            "",
            "",
            [],
            910,
            "        for id in range(len(watched)):",
            [],
            false
          ],
          [
            911,
            "",
            "",
            [],
            911,
            "            self.assertEqual(apigroups[id][&#39;watched_review_group&#39;][&#39;name&#39;],",
            [],
            false
          ],
          [
            912,
            "",
            "",
            [],
            912,
            "                             watched[id].name)",
            [],
            false
          ],
          [
            913,
            "",
            "",
            [],
            913,
            "",
            [],
            false
          ],
          [
            914,
            "",
            "",
            [],
            914,
            "    def test_get_watched_review_groups_with_site_no_access(self):",
            [],
            false
          ],
          [
            915,
            "",
            "",
            [],
            915,
            "        &quot;&quot;&quot;Testing the GET users/&lt;username&gt;/watched/review-groups/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            916,
            "",
            "",
            [],
            916,
            "        watched_url = \\",
            [],
            false
          ],
          [
            917,
            "",
            "",
            [],
            917,
            "            local_site_reverse(&#39;watched-review-groups-resource&#39;,",
            [],
            false
          ],
          [
            918,
            "",
            "",
            [],
            918,
            "                               local_site_name=self.local_site_name,",
            [],
            false
          ],
          [
            919,
            "",
            "",
            [],
            919,
            "                               kwargs={ &#39;username&#39;: self.user.username })",
            [],
            false
          ],
          [
            920,
            "",
            "",
            [],
            920,
            "",
            [],
            false
          ],
          [
            921,
            "",
            "",
            [],
            921,
            "        rsp = self.apiGet(self.get_list_url(self.user.username,",
            [],
            false
          ],
          [
            922,
            "",
            "",
            [],
            922,
            "                                             self.local_site_name),",
            [],
            false
          ],
          [
            923,
            "",
            "",
            [],
            923,
            "                          expected_status=403)",
            [],
            false
          ],
          [
            924,
            "",
            "",
            [],
            924,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;fail&#39;)",
            [],
            false
          ],
          [
            925,
            "",
            "",
            [],
            925,
            "        self.assertEqual(rsp[&#39;err&#39;][&#39;code&#39;], PERMISSION_DENIED.code)",
            [],
            false
          ],
          [
            926,
            "",
            "",
            [],
            926,
            "",
            [],
            false
          ],
          [
            927,
            "",
            "",
            [],
            927,
            "    def get_list_url(self, username, local_site_name=None):",
            [],
            false
          ],
          [
            928,
            "",
            "",
            [],
            928,
            "        return local_site_reverse(&#39;watched-review-groups-resource&#39;,",
            [],
            false
          ],
          [
            929,
            "",
            "",
            [],
            929,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            930,
            "",
            "",
            [],
            930,
            "                                  kwargs={",
            [],
            false
          ],
          [
            931,
            "",
            "",
            [],
            931,
            "                                      &#39;username&#39;: username,",
            [],
            false
          ],
          [
            932,
            "",
            "",
            [],
            932,
            "                                  })",
            [],
            false
          ],
          [
            933,
            "",
            "",
            [],
            933,
            "",
            [],
            false
          ],
          [
            934,
            "",
            "",
            [],
            934,
            "    def get_item_url(self, username, object_id, local_site_name=None):",
            [],
            false
          ],
          [
            935,
            "",
            "",
            [],
            935,
            "        return local_site_reverse(&#39;watched-review-group-resource&#39;,",
            [],
            false
          ],
          [
            936,
            "",
            "",
            [],
            936,
            "                                  local_site_name=local_site_name,",
            [],
            false
          ],
          [
            937,
            "",
            "",
            [],
            937,
            "                                  kwargs={",
            [],
            false
          ],
          [
            938,
            "",
            "",
            [],
            938,
            "                                      &#39;username&#39;: username,",
            [],
            false
          ],
          [
            939,
            "",
            "",
            [],
            939,
            "                                      &#39;watched_obj_id&#39;: object_id,",
            [],
            false
          ],
          [
            940,
            "",
            "",
            [],
            940,
            "                                  })",
            [],
            false
          ],
          [
            941,
            "",
            "",
            [],
            941,
            "",
            [],
            false
          ],
          [
            942,
            "",
            "",
            [],
            942,
            "",
            [],
            false
          ],
          [
            943,
            "",
            "",
            [],
            943,
            "class ReviewRequestResourceTests(BaseWebAPITestCase):",
            [],
            false
          ],
          [
            944,
            "",
            "",
            [],
            944,
            "    &quot;&quot;&quot;Testing the ReviewRequestResource API tests.&quot;&quot;&quot;",
            [],
            false
          ],
          [
            945,
            "",
            "",
            [],
            945,
            "",
            [],
            false
          ],
          [
            946,
            "",
            "",
            [],
            946,
            "    def test_get_reviewrequests(self):",
            [],
            false
          ],
          [
            947,
            "",
            "",
            [],
            947,
            "        &quot;&quot;&quot;Testing the GET review-requests/ API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            948,
            "",
            "",
            [],
            948,
            "        rsp = self.apiGet(self.get_list_url())",
            [],
            false
          ],
          [
            949,
            "",
            "",
            [],
            949,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            950,
            "",
            "",
            [],
            950,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            951,
            "",
            "",
            [],
            951,
            "                         ReviewRequest.objects.public().count())",
            [],
            false
          ],
          [
            952,
            "",
            "",
            [],
            952,
            "",
            [],
            false
          ],
          [
            953,
            "",
            "",
            [],
            953,
            "    def test_get_reviewrequests_with_site(self):",
            [],
            false
          ],
          [
            954,
            "",
            "",
            [],
            954,
            "        &quot;&quot;&quot;Testing the GET review-requests/ API with a local site&quot;&quot;&quot;",
            [],
            false
          ],
          [
            955,
            "",
            "",
            [],
            955,
            "        self.client.logout()",
            [],
            false
          ],
          [
            956,
            "",
            "",
            [],
            956,
            "        self.client.login(username=&#39;doc&#39;, password=&#39;doc&#39;)",
            [],
            false
          ],
          [
            957,
            "",
            "",
            [],
            957,
            "        local_site = LocalSite.objects.get(name=self.local_site_name)",
            [],
            false
          ],
          [
            958,
            "",
            "",
            [],
            958,
            "",
            [],
            false
          ],
          [
            959,
            "",
            "",
            [],
            959,
            "        rsp = self.apiGet(self.get_list_url(self.local_site_name))",
            [],
            false
          ],
          [
            960,
            "",
            "",
            [],
            960,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            961,
            "",
            "",
            [],
            961,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            962,
            "",
            "",
            [],
            962,
            "                         ReviewRequest.objects.public(",
            [],
            false
          ],
          [
            963,
            "",
            "",
            [],
            963,
            "                             local_site=local_site).count())",
            [],
            false
          ],
          [
            964,
            "",
            "",
            [],
            964,
            "",
            [],
            false
          ],
          [
            965,
            "",
            "",
            [],
            965,
            "    def test_get_reviewrequests_with_site_no_access(self):",
            [],
            false
          ],
          [
            966,
            "",
            "",
            [],
            966,
            "        &quot;&quot;&quot;Testing the GET review-requests/ API with a local site and Permission Denied error&quot;&quot;&quot;",
            [],
            false
          ],
          [
            967,
            "",
            "",
            [],
            967,
            "        self.apiGet(self.get_list_url(self.local_site_name),",
            [],
            false
          ],
          [
            968,
            "",
            "",
            [],
            968,
            "                    expected_status=403)",
            [],
            false
          ],
          [
            969,
            "",
            "",
            [],
            969,
            "",
            [],
            false
          ],
          [
            970,
            "",
            "",
            [],
            970,
            "    def test_get_reviewrequests_with_status(self):",
            [],
            false
          ],
          [
            971,
            "",
            "",
            [],
            971,
            "        &quot;&quot;&quot;Testing the GET review-requests/?status= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            972,
            "",
            "",
            [],
            972,
            "        url = self.get_list_url()",
            [],
            false
          ],
          [
            973,
            "",
            "",
            [],
            973,
            "",
            [],
            false
          ],
          [
            974,
            "",
            "",
            [],
            974,
            "        rsp = self.apiGet(url, {&#39;status&#39;: &#39;submitted&#39;})",
            [],
            false
          ],
          [
            975,
            "",
            "",
            [],
            975,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            976,
            "",
            "",
            [],
            976,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            977,
            "",
            "",
            [],
            977,
            "                         ReviewRequest.objects.public(status=&#39;S&#39;).count())",
            [],
            false
          ],
          [
            978,
            "",
            "",
            [],
            978,
            "",
            [],
            false
          ],
          [
            979,
            "",
            "",
            [],
            979,
            "        rsp = self.apiGet(url, {&#39;status&#39;: &#39;discarded&#39;})",
            [],
            false
          ],
          [
            980,
            "",
            "",
            [],
            980,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            981,
            "",
            "",
            [],
            981,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            982,
            "",
            "",
            [],
            982,
            "                         ReviewRequest.objects.public(status=&#39;D&#39;).count())",
            [],
            false
          ],
          [
            983,
            "",
            "",
            [],
            983,
            "",
            [],
            false
          ],
          [
            984,
            "",
            "",
            [],
            984,
            "        rsp = self.apiGet(url, {&#39;status&#39;: &#39;all&#39;})",
            [],
            false
          ],
          [
            985,
            "",
            "",
            [],
            985,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            986,
            "",
            "",
            [],
            986,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            987,
            "",
            "",
            [],
            987,
            "                         ReviewRequest.objects.public(status=None).count())",
            [],
            false
          ],
          [
            988,
            "",
            "",
            [],
            988,
            "",
            [],
            false
          ],
          [
            989,
            "",
            "",
            [],
            989,
            "    def test_get_reviewrequests_with_counts_only(self):",
            [],
            false
          ],
          [
            990,
            "",
            "",
            [],
            990,
            "        &quot;&quot;&quot;Testing the GET review-requests/?counts-only=1 API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            991,
            "",
            "",
            [],
            991,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            992,
            "",
            "",
            [],
            992,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            993,
            "",
            "",
            [],
            993,
            "        })",
            [],
            false
          ],
          [
            994,
            "",
            "",
            [],
            994,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            995,
            "",
            "",
            [],
            995,
            "        self.assertEqual(rsp[&#39;count&#39;], ReviewRequest.objects.public().count())",
            [],
            false
          ],
          [
            996,
            "",
            "",
            [],
            996,
            "",
            [],
            false
          ],
          [
            997,
            "",
            "",
            [],
            997,
            "    def test_get_reviewrequests_with_to_groups(self):",
            [],
            false
          ],
          [
            998,
            "",
            "",
            [],
            998,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-groups= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            999,
            "",
            "",
            [],
            999,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1000,
            "",
            "",
            [],
            1000,
            "            &#39;to-groups&#39;: &#39;devgroup&#39;,",
            [],
            false
          ],
          [
            1001,
            "",
            "",
            [],
            1001,
            "        })",
            [],
            false
          ],
          [
            1002,
            "",
            "",
            [],
            1002,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1003,
            "",
            "",
            [],
            1003,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1004,
            "",
            "",
            [],
            1004,
            "                         ReviewRequest.objects.to_group(&quot;devgroup&quot;,",
            [],
            false
          ],
          [
            1005,
            "",
            "",
            [],
            1005,
            "                                                        None).count())",
            [],
            false
          ],
          [
            1006,
            "",
            "",
            [],
            1006,
            "",
            [],
            false
          ],
          [
            1007,
            "",
            "",
            [],
            1007,
            "    def test_get_reviewrequests_with_to_groups_and_status(self):",
            [],
            false
          ],
          [
            1008,
            "",
            "",
            [],
            1008,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-groups=&amp;status= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1009,
            "",
            "",
            [],
            1009,
            "        url = self.get_list_url()",
            [],
            false
          ],
          [
            1010,
            "",
            "",
            [],
            1010,
            "",
            [],
            false
          ],
          [
            1011,
            "",
            "",
            [],
            1011,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1012,
            "",
            "",
            [],
            1012,
            "            &#39;status&#39;: &#39;submitted&#39;,",
            [],
            false
          ],
          [
            1013,
            "",
            "",
            [],
            1013,
            "            &#39;to-groups&#39;: &#39;devgroup&#39;,",
            [],
            false
          ],
          [
            1014,
            "",
            "",
            [],
            1014,
            "        })",
            [],
            false
          ],
          [
            1015,
            "",
            "",
            [],
            1015,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1016,
            "",
            "",
            [],
            1016,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1017,
            "",
            "",
            [],
            1017,
            "            ReviewRequest.objects.to_group(&quot;devgroup&quot;, None,",
            [],
            false
          ],
          [
            1018,
            "",
            "",
            [],
            1018,
            "                                           status=&#39;S&#39;).count())",
            [],
            false
          ],
          [
            1019,
            "",
            "",
            [],
            1019,
            "",
            [],
            false
          ],
          [
            1020,
            "",
            "",
            [],
            1020,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1021,
            "",
            "",
            [],
            1021,
            "            &#39;status&#39;: &#39;discarded&#39;,",
            [],
            false
          ],
          [
            1022,
            "",
            "",
            [],
            1022,
            "            &#39;to-groups&#39;: &#39;devgroup&#39;,",
            [],
            false
          ],
          [
            1023,
            "",
            "",
            [],
            1023,
            "        })",
            [],
            false
          ],
          [
            1024,
            "",
            "",
            [],
            1024,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1025,
            "",
            "",
            [],
            1025,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1026,
            "",
            "",
            [],
            1026,
            "            ReviewRequest.objects.to_group(&quot;devgroup&quot;, None,",
            [],
            false
          ],
          [
            1027,
            "",
            "",
            [],
            1027,
            "                                           status=&#39;D&#39;).count())",
            [],
            false
          ],
          [
            1028,
            "",
            "",
            [],
            1028,
            "",
            [],
            false
          ],
          [
            1029,
            "",
            "",
            [],
            1029,
            "    def test_get_reviewrequests_with_to_groups_and_counts_only(self):",
            [],
            false
          ],
          [
            1030,
            "",
            "",
            [],
            1030,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-groups=&amp;counts-only=1 API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1031,
            "",
            "",
            [],
            1031,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1032,
            "",
            "",
            [],
            1032,
            "            &#39;to-groups&#39;: &#39;devgroup&#39;,",
            [],
            false
          ],
          [
            1033,
            "",
            "",
            [],
            1033,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            1034,
            "",
            "",
            [],
            1034,
            "        })",
            [],
            false
          ],
          [
            1035,
            "",
            "",
            [],
            1035,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1036,
            "",
            "",
            [],
            1036,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1037,
            "",
            "",
            [],
            1037,
            "                         ReviewRequest.objects.to_group(&quot;devgroup&quot;,",
            [],
            false
          ],
          [
            1038,
            "",
            "",
            [],
            1038,
            "                                                        None).count())",
            [],
            false
          ],
          [
            1039,
            "",
            "",
            [],
            1039,
            "",
            [],
            false
          ],
          [
            1040,
            "",
            "",
            [],
            1040,
            "    def test_get_reviewrequests_with_to_users(self):",
            [],
            false
          ],
          [
            1041,
            "",
            "",
            [],
            1041,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-users= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1042,
            "",
            "",
            [],
            1042,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1043,
            "",
            "",
            [],
            1043,
            "            &#39;to-users&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1044,
            "",
            "",
            [],
            1044,
            "        })",
            [],
            false
          ],
          [
            1045,
            "",
            "",
            [],
            1045,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1046,
            "",
            "",
            [],
            1046,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1047,
            "",
            "",
            [],
            1047,
            "                         ReviewRequest.objects.to_user(&quot;grumpy&quot;).count())",
            [],
            false
          ],
          [
            1048,
            "",
            "",
            [],
            1048,
            "",
            [],
            false
          ],
          [
            1049,
            "",
            "",
            [],
            1049,
            "    def test_get_reviewrequests_with_to_users_and_status(self):",
            [],
            false
          ],
          [
            1050,
            "",
            "",
            [],
            1050,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-users=&amp;status= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1051,
            "",
            "",
            [],
            1051,
            "        url = self.get_list_url()",
            [],
            false
          ],
          [
            1052,
            "",
            "",
            [],
            1052,
            "",
            [],
            false
          ],
          [
            1053,
            "",
            "",
            [],
            1053,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1054,
            "",
            "",
            [],
            1054,
            "            &#39;status&#39;: &#39;submitted&#39;,",
            [],
            false
          ],
          [
            1055,
            "",
            "",
            [],
            1055,
            "            &#39;to-users&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1056,
            "",
            "",
            [],
            1056,
            "        })",
            [],
            false
          ],
          [
            1057,
            "",
            "",
            [],
            1057,
            "",
            [],
            false
          ],
          [
            1058,
            "",
            "",
            [],
            1058,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1059,
            "",
            "",
            [],
            1059,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1060,
            "",
            "",
            [],
            1060,
            "            ReviewRequest.objects.to_user(&quot;grumpy&quot;, status=&#39;S&#39;).count())",
            [],
            false
          ],
          [
            1061,
            "",
            "",
            [],
            1061,
            "",
            [],
            false
          ],
          [
            1062,
            "",
            "",
            [],
            1062,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1063,
            "",
            "",
            [],
            1063,
            "            &#39;status&#39;: &#39;discarded&#39;,",
            [],
            false
          ],
          [
            1064,
            "",
            "",
            [],
            1064,
            "            &#39;to-users&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1065,
            "",
            "",
            [],
            1065,
            "        })",
            [],
            false
          ],
          [
            1066,
            "",
            "",
            [],
            1066,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1067,
            "",
            "",
            [],
            1067,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1068,
            "",
            "",
            [],
            1068,
            "            ReviewRequest.objects.to_user(&quot;grumpy&quot;, status=&#39;D&#39;).count())",
            [],
            false
          ],
          [
            1069,
            "",
            "",
            [],
            1069,
            "",
            [],
            false
          ],
          [
            1070,
            "",
            "",
            [],
            1070,
            "    def test_get_reviewrequests_with_to_users_and_counts_only(self):",
            [],
            false
          ],
          [
            1071,
            "",
            "",
            [],
            1071,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-users=&amp;counts-only=1 API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1072,
            "",
            "",
            [],
            1072,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1073,
            "",
            "",
            [],
            1073,
            "            &#39;to-users&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1074,
            "",
            "",
            [],
            1074,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            1075,
            "",
            "",
            [],
            1075,
            "        })",
            [],
            false
          ],
          [
            1076,
            "",
            "",
            [],
            1076,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1077,
            "",
            "",
            [],
            1077,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1078,
            "",
            "",
            [],
            1078,
            "                         ReviewRequest.objects.to_user(&quot;grumpy&quot;).count())",
            [],
            false
          ],
          [
            1079,
            "",
            "",
            [],
            1079,
            "",
            [],
            false
          ],
          [
            1080,
            "",
            "",
            [],
            1080,
            "    def test_get_reviewrequests_with_to_users_directly(self):",
            [],
            false
          ],
          [
            1081,
            "",
            "",
            [],
            1081,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-users-directly= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1082,
            "",
            "",
            [],
            1082,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1083,
            "",
            "",
            [],
            1083,
            "            &#39;to-users-directly&#39;: &#39;doc&#39;,",
            [],
            false
          ],
          [
            1084,
            "",
            "",
            [],
            1084,
            "        })",
            [],
            false
          ],
          [
            1085,
            "",
            "",
            [],
            1085,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1086,
            "",
            "",
            [],
            1086,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1087,
            "",
            "",
            [],
            1087,
            "                         ReviewRequest.objects.to_user_directly(&quot;doc&quot;).count())",
            [],
            false
          ],
          [
            1088,
            "",
            "",
            [],
            1088,
            "",
            [],
            false
          ],
          [
            1089,
            "",
            "",
            [],
            1089,
            "    def test_get_reviewrequests_with_to_users_directly_and_status(self):",
            [],
            false
          ],
          [
            1090,
            "",
            "",
            [],
            1090,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-users-directly=&amp;status= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1091,
            "",
            "",
            [],
            1091,
            "        url = self.get_list_url()",
            [],
            false
          ],
          [
            1092,
            "",
            "",
            [],
            1092,
            "",
            [],
            false
          ],
          [
            1093,
            "",
            "",
            [],
            1093,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1094,
            "",
            "",
            [],
            1094,
            "            &#39;status&#39;: &#39;submitted&#39;,",
            [],
            false
          ],
          [
            1095,
            "",
            "",
            [],
            1095,
            "            &#39;to-users-directly&#39;: &#39;doc&#39;",
            [],
            false
          ],
          [
            1096,
            "",
            "",
            [],
            1096,
            "        })",
            [],
            false
          ],
          [
            1097,
            "",
            "",
            [],
            1097,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1098,
            "",
            "",
            [],
            1098,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1099,
            "",
            "",
            [],
            1099,
            "            ReviewRequest.objects.to_user_directly(&quot;doc&quot;, status=&#39;S&#39;).count())",
            [],
            false
          ],
          [
            1100,
            "",
            "",
            [],
            1100,
            "",
            [],
            false
          ],
          [
            1101,
            "",
            "",
            [],
            1101,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1102,
            "",
            "",
            [],
            1102,
            "            &#39;status&#39;: &#39;discarded&#39;,",
            [],
            false
          ],
          [
            1103,
            "",
            "",
            [],
            1103,
            "            &#39;to-users-directly&#39;: &#39;doc&#39;",
            [],
            false
          ],
          [
            1104,
            "",
            "",
            [],
            1104,
            "        })",
            [],
            false
          ],
          [
            1105,
            "",
            "",
            [],
            1105,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1106,
            "",
            "",
            [],
            1106,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1107,
            "",
            "",
            [],
            1107,
            "            ReviewRequest.objects.to_user_directly(&quot;doc&quot;, status=&#39;D&#39;).count())",
            [],
            false
          ],
          [
            1108,
            "",
            "",
            [],
            1108,
            "",
            [],
            false
          ],
          [
            1109,
            "",
            "",
            [],
            1109,
            "    def test_get_reviewrequests_with_to_users_directly_and_counts_only(self):",
            [],
            false
          ],
          [
            1110,
            "",
            "",
            [],
            1110,
            "        &quot;&quot;&quot;Testing the GET review-requests/?to-users-directly=&amp;counts-only=1 API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1111,
            "",
            "",
            [],
            1111,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1112,
            "",
            "",
            [],
            1112,
            "            &#39;to-users-directly&#39;: &#39;doc&#39;,",
            [],
            false
          ],
          [
            1113,
            "",
            "",
            [],
            1113,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            1114,
            "",
            "",
            [],
            1114,
            "        })",
            [],
            false
          ],
          [
            1115,
            "",
            "",
            [],
            1115,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1116,
            "",
            "",
            [],
            1116,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1117,
            "",
            "",
            [],
            1117,
            "                         ReviewRequest.objects.to_user_directly(&quot;doc&quot;).count())",
            [],
            false
          ],
          [
            1118,
            "",
            "",
            [],
            1118,
            "",
            [],
            false
          ],
          [
            1119,
            "",
            "",
            [],
            1119,
            "    def test_get_reviewrequests_with_from_user(self):",
            [],
            false
          ],
          [
            1120,
            "",
            "",
            [],
            1120,
            "        &quot;&quot;&quot;Testing the GET review-requests/?from-user= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1121,
            "",
            "",
            [],
            1121,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1122,
            "",
            "",
            [],
            1122,
            "            &#39;from-user&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1123,
            "",
            "",
            [],
            1123,
            "        })",
            [],
            false
          ],
          [
            1124,
            "",
            "",
            [],
            1124,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1125,
            "",
            "",
            [],
            1125,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1126,
            "",
            "",
            [],
            1126,
            "                         ReviewRequest.objects.from_user(&quot;grumpy&quot;).count())",
            [],
            false
          ],
          [
            1127,
            "",
            "",
            [],
            1127,
            "",
            [],
            false
          ],
          [
            1128,
            "",
            "",
            [],
            1128,
            "    def test_get_reviewrequests_with_from_user_and_status(self):",
            [],
            false
          ],
          [
            1129,
            "",
            "",
            [],
            1129,
            "        &quot;&quot;&quot;Testing the GET review-requests/?from-user=&amp;status= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1130,
            "",
            "",
            [],
            1130,
            "        url = self.get_list_url()",
            [],
            false
          ],
          [
            1131,
            "",
            "",
            [],
            1131,
            "",
            [],
            false
          ],
          [
            1132,
            "",
            "",
            [],
            1132,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1133,
            "",
            "",
            [],
            1133,
            "            &#39;status&#39;: &#39;submitted&#39;,",
            [],
            false
          ],
          [
            1134,
            "",
            "",
            [],
            1134,
            "            &#39;from-user&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1135,
            "",
            "",
            [],
            1135,
            "        })",
            [],
            false
          ],
          [
            1136,
            "",
            "",
            [],
            1136,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1137,
            "",
            "",
            [],
            1137,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1138,
            "",
            "",
            [],
            1138,
            "            ReviewRequest.objects.from_user(&quot;grumpy&quot;, status=&#39;S&#39;).count())",
            [],
            false
          ],
          [
            1139,
            "",
            "",
            [],
            1139,
            "",
            [],
            false
          ],
          [
            1140,
            "",
            "",
            [],
            1140,
            "        rsp = self.apiGet(url, {",
            [],
            false
          ],
          [
            1141,
            "",
            "",
            [],
            1141,
            "            &#39;status&#39;: &#39;discarded&#39;,",
            [],
            false
          ],
          [
            1142,
            "",
            "",
            [],
            1142,
            "            &#39;from-user&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1143,
            "",
            "",
            [],
            1143,
            "        })",
            [],
            false
          ],
          [
            1144,
            "",
            "",
            [],
            1144,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1145,
            "",
            "",
            [],
            1145,
            "        self.assertEqual(len(rsp[&#39;review_requests&#39;]),",
            [],
            false
          ],
          [
            1146,
            "",
            "",
            [],
            1146,
            "            ReviewRequest.objects.from_user(&quot;grumpy&quot;, status=&#39;D&#39;).count())",
            [],
            false
          ],
          [
            1147,
            "",
            "",
            [],
            1147,
            "",
            [],
            false
          ],
          [
            1148,
            "",
            "",
            [],
            1148,
            "    def test_get_reviewrequests_with_from_user_and_counts_only(self):",
            [],
            false
          ],
          [
            1149,
            "",
            "",
            [],
            1149,
            "        &quot;&quot;&quot;Testing the GET review-requests/?from-user=&amp;counts-only=1 API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1150,
            "",
            "",
            [],
            1150,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1151,
            "",
            "",
            [],
            1151,
            "            &#39;from-user&#39;: &#39;grumpy&#39;,",
            [],
            false
          ],
          [
            1152,
            "",
            "",
            [],
            1152,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            1153,
            "",
            "",
            [],
            1153,
            "        })",
            [],
            false
          ],
          [
            1154,
            "",
            "",
            [],
            1154,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1155,
            "",
            "",
            [],
            1155,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1156,
            "",
            "",
            [],
            1156,
            "                         ReviewRequest.objects.from_user(&quot;grumpy&quot;).count())",
            [],
            false
          ],
          [
            1157,
            "",
            "",
            [],
            1157,
            "",
            [],
            false
          ],
          [
            1158,
            "",
            "",
            [],
            1158,
            "    def test_get_reviewrequests_with_time_added_from(self):",
            [],
            false
          ],
          [
            1159,
            "",
            "",
            [],
            1159,
            "        &quot;&quot;&quot;Testing the GET review-requests/?time-added-from= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1160,
            "",
            "",
            [],
            1160,
            "        start_index = 3",
            [],
            false
          ],
          [
            1161,
            "",
            "",
            [],
            1161,
            "",
            [],
            false
          ],
          [
            1162,
            "",
            "",
            [],
            1162,
            "        public_review_requests = \\",
            [],
            false
          ],
          [
            1163,
            "",
            "",
            [],
            1163,
            "            ReviewRequest.objects.public().order_by(&#39;time_added&#39;)",
            [],
            false
          ],
          [
            1164,
            "",
            "",
            [],
            1164,
            "        r = public_review_requests[start_index]",
            [],
            false
          ],
          [
            1165,
            "",
            "",
            [],
            1165,
            "        timestamp = r.time_added.isoformat()",
            [],
            false
          ],
          [
            1166,
            "",
            "",
            [],
            1166,
            "",
            [],
            false
          ],
          [
            1167,
            "",
            "",
            [],
            1167,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1168,
            "",
            "",
            [],
            1168,
            "            &#39;time-added-from&#39;: timestamp,",
            [],
            false
          ],
          [
            1169,
            "",
            "",
            [],
            1169,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            1170,
            "",
            "",
            [],
            1170,
            "        })",
            [],
            false
          ],
          [
            1171,
            "",
            "",
            [],
            1171,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1172,
            "",
            "",
            [],
            1172,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1173,
            "",
            "",
            [],
            1173,
            "                         public_review_requests.count() - start_index)",
            [],
            false
          ],
          [
            1174,
            "",
            "",
            [],
            1174,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1175,
            "",
            "",
            [],
            1175,
            "                         public_review_requests.filter(",
            [],
            false
          ],
          [
            1176,
            "",
            "",
            [],
            1176,
            "                            time_added__gte=r.time_added).count())",
            [],
            false
          ],
          [
            1177,
            "",
            "",
            [],
            1177,
            "",
            [],
            false
          ],
          [
            1178,
            "",
            "",
            [],
            1178,
            "    def test_get_reviewrequests_with_time_added_to(self):",
            [],
            false
          ],
          [
            1179,
            "",
            "",
            [],
            1179,
            "        &quot;&quot;&quot;Testing the GET review-requests/?time-added-to= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1180,
            "",
            "",
            [],
            1180,
            "        start_index = 3",
            [],
            false
          ],
          [
            1181,
            "",
            "",
            [],
            1181,
            "",
            [],
            false
          ],
          [
            1182,
            "",
            "",
            [],
            1182,
            "        public_review_requests = \\",
            [],
            false
          ],
          [
            1183,
            "",
            "",
            [],
            1183,
            "            ReviewRequest.objects.public().order_by(&#39;time_added&#39;)",
            [],
            false
          ],
          [
            1184,
            "",
            "",
            [],
            1184,
            "        r = public_review_requests[start_index]",
            [],
            false
          ],
          [
            1185,
            "",
            "",
            [],
            1185,
            "        timestamp = r.time_added.isoformat()",
            [],
            false
          ],
          [
            1186,
            "",
            "",
            [],
            1186,
            "",
            [],
            false
          ],
          [
            1187,
            "",
            "",
            [],
            1187,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1188,
            "",
            "",
            [],
            1188,
            "            &#39;time-added-to&#39;: timestamp,",
            [],
            false
          ],
          [
            1189,
            "",
            "",
            [],
            1189,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            1190,
            "",
            "",
            [],
            1190,
            "        })",
            [],
            false
          ],
          [
            1191,
            "",
            "",
            [],
            1191,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1192,
            "",
            "",
            [],
            1192,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1193,
            "",
            "",
            [],
            1193,
            "                         public_review_requests.count() - start_index + 1)",
            [],
            false
          ],
          [
            1194,
            "",
            "",
            [],
            1194,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1195,
            "",
            "",
            [],
            1195,
            "                         public_review_requests.filter(",
            [],
            false
          ],
          [
            1196,
            "",
            "",
            [],
            1196,
            "                             time_added__lt=r.time_added).count())",
            [],
            false
          ],
          [
            1197,
            "",
            "",
            [],
            1197,
            "",
            [],
            false
          ],
          [
            1198,
            "",
            "",
            [],
            1198,
            "    def test_get_reviewrequests_with_last_updated_from(self):",
            [],
            false
          ],
          [
            1199,
            "",
            "",
            [],
            1199,
            "        &quot;&quot;&quot;Testing the GET review-requests/?last-updated-from= API&quot;&quot;&quot;",
            [],
            false
          ],
          [
            1200,
            "",
            "",
            [],
            1200,
            "        start_index = 3",
            [],
            false
          ],
          [
            1201,
            "",
            "",
            [],
            1201,
            "",
            [],
            false
          ],
          [
            1202,
            "",
            "",
            [],
            1202,
            "        public_review_requests = \\",
            [],
            false
          ],
          [
            1203,
            "",
            "",
            [],
            1203,
            "            ReviewRequest.objects.public().order_by(&#39;last_updated&#39;)",
            [],
            false
          ],
          [
            1204,
            "",
            "",
            [],
            1204,
            "        r = public_review_requests[start_index]",
            [],
            false
          ],
          [
            1205,
            "",
            "",
            [],
            1205,
            "        timestamp = r.last_updated.isoformat()",
            [],
            false
          ],
          [
            1206,
            "",
            "",
            [],
            1206,
            "",
            [],
            false
          ],
          [
            1207,
            "",
            "",
            [],
            1207,
            "        rsp = self.apiGet(self.get_list_url(), {",
            [],
            false
          ],
          [
            1208,
            "",
            "",
            [],
            1208,
            "            &#39;last-updated-from&#39;: timestamp,",
            [],
            false
          ],
          [
            1209,
            "",
            "",
            [],
            1209,
            "            &#39;counts-only&#39;: 1,",
            [],
            false
          ],
          [
            1210,
            "",
            "",
            [],
            1210,
            "        })",
            [],
            false
          ],
          [
            1211,
            "",
            "",
            [],
            1211,
            "        self.assertEqual(rsp[&#39;stat&#39;], &#39;ok&#39;)",
            [],
            false
          ],
          [
            1212,
            "",
            "",
            [],
            1212,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1213,
            "",
            "",
            [],
            1213,
            "                         public_review_requests.count() - start_index)",
            [],
            false
          ],
          [
            1214,
            "",
            "",
            [],
            1214,
            "        self.assertEqual(rsp[&#39;count&#39;],",
            [],
            false
          ],
          [
            1215,
            "",
            "",
            [],
            1215,
            "                         public_review_requests.filter(",
            [],
            false
          ],
          [
            1216,
            "",
            "",
            [],
            1216,
            "                             last_updated__gte=r.last_updated).count())",
            [],
            false
          ],
          [
            1217,
            "",
            "",
            [],
            1217,
            "",
            [],
            false
          ],
          [
            1218,
            "",
            "",
            [],
            1218,
            "    def test_get_reviewrequests_with_last_updated_to(self):",
            [],
            false
          ],
          [<