diff --git a/rbtools/api/tests.py b/rbtools/api/tests.py
index 38fae358cb2aad185c6f273d018d7ec6ee01eb7f..ceee88fc35c432228dc03839eadbf551ad4ada0c 100644
--- a/rbtools/api/tests.py
+++ b/rbtools/api/tests.py
@@ -505,9 +505,11 @@ class MockResponse(object):
         self.body = body
 
         if self.body:
-            self.headers['Content-Type'] = 'text/plain'
             self.headers['Content-Length'] = len(body)
 
+            if 'Content-Type' not in self.headers:
+                self.headers['Content-Type'] = 'text/plain'
+
     def info(self):
         """Get the response headers."""
         return self.headers
diff --git a/rbtools/clients/svn.py b/rbtools/clients/svn.py
index df0771abe90740f127c8be86b21a6f58fbb95b81..fa9989e6347500724f8ac1da848cf562bd244282 100644
--- a/rbtools/clients/svn.py
+++ b/rbtools/clients/svn.py
@@ -921,25 +921,76 @@ class SVNClient(SCMClient):
 
 
 class SVNRepositoryInfo(RepositoryInfo):
+    """Information on a Subversion repository.
+
+    This stores information on the path and, optionally, UUID of a Subversion
+    repository. It can match a local repository against those on a Review Board
+    server.
+
+    Attributes:
+        repository_id (int):
+            ID of the repository in the API. This is used primarily for
+            testing purposes, and is not guaranteed to be set.
+
+        uuid (unicode):
+            UUID of the Subversion repository.
     """
-    A representation of a SVN source code repository. This version knows how to
-    find a matching repository on the server even if the URLs differ.
-    """
-    def __init__(self, path, base_path, uuid, supports_parent_diffs=False):
-        RepositoryInfo.__init__(self, path, base_path,
-                                supports_parent_diffs=supports_parent_diffs)
+
+    def __init__(self, path, base_path, uuid, repository_id=None):
+        """Initialize the repository information.
+
+        Args:
+            path (unicode):
+                Subversion checkout path.
+
+            base_path (unicode):
+                Root of the Subversion repository.
+
+            uuid (unicode):
+                UUID of the Subversion repository.
+
+            repository_id (int, optional):
+                ID of the repository in the API. This is used primarily for
+                testing purposes, and is not guaranteed to be set.
+        """
+        super(SVNRepositoryInfo, self).__init__(path, base_path)
+
         self.uuid = uuid
+        self.repository_id = repository_id
 
     def find_server_repository_info(self, server):
-        """
+        """Return server-side information on the current Subversion repository.
+
         The point of this function is to find a repository on the server that
         matches self, even if the paths aren't the same. (For example, if self
         uses an 'http' path, but the server uses a 'file' path for the same
         repository.) It does this by comparing repository UUIDs. If the
         repositories use the same path, you'll get back self, otherwise you'll
         get a different SVNRepositoryInfo object (with a different path).
+
+        Args:
+            server (rbtools.api.resource.RootResource):
+                The root resource for the Review Board server.
+
+        Returns:
+            SVNRepositoryInfo:
+            The server-side information for this repository.
         """
+        # Since all_items is a generator, and we need to process the list of
+        # repositories twice, we're going to keep a cached list of repositories
+        # that we'll add to as we iterate through the first time. That way,
+        # we can iterate through a second time, without performing another
+        # call to the server.
+        #
+        # Hopefully we'll match a repository in the first (less expensive) loop
+        # and won't need it.
+        #
+        # Note also that we're not fetching all pages up-front, as that could
+        # lead to a lot of unnecessary API requests if the repository in
+        # question is found before the last page of results in the first for
+        # loop.
         repositories = server.get_repositories(tool='Subversion').all_items
+        cached_repos = []
 
         # Do two paths. The first will be to try to find a matching entry
         # by path/mirror path. If we don't find anything, then the second will
@@ -948,10 +999,13 @@ class SVNRepositoryInfo(RepositoryInfo):
             if (self.path == repository['path'] or
                 ('mirror_path' in repository and
                  self.path == repository['mirror_path'])):
+                self.repository_id = repository.id
                 return self
 
+            cached_repos.append(repository)
+
         # We didn't find our locally matched repository, so scan based on UUID.
-        for repository in repositories:
+        for repository in cached_repos:
             try:
                 info = repository.get_info()
 
@@ -964,7 +1018,8 @@ class SVNRepositoryInfo(RepositoryInfo):
             relpath = self._get_relative_path(self.base_path, repos_base_path)
 
             if relpath:
-                return SVNRepositoryInfo(info['url'], relpath, self.uuid)
+                return SVNRepositoryInfo(info['url'], relpath, self.uuid,
+                                         repository_id=repository.id)
 
         # We didn't find a matching repository on the server. We'll just return
         # self and hope for the best. In reality, we'll likely fail, but we
diff --git a/rbtools/clients/tests.py b/rbtools/clients/tests.py
index 6d3c1905522489bb38168c453053db46a57a17f6..053929a68e7a5baba4fc309cffd609ca5fc4c6f1 100644
--- a/rbtools/clients/tests.py
+++ b/rbtools/clients/tests.py
@@ -1,5 +1,6 @@
 from __future__ import print_function, unicode_literals
 
+import json
 import os
 import re
 import sys
@@ -10,10 +11,14 @@ from random import randint
 from tempfile import mktemp
 from textwrap import dedent
 
+from kgb import SpyAgency
 from nose import SkipTest
 from six.moves import cStringIO as StringIO
+from six.moves.urllib.request import urlopen
 
 from rbtools.api.capabilities import Capabilities
+from rbtools.api.client import RBClient
+from rbtools.api.tests import MockResponse
 from rbtools.clients import RepositoryInfo
 from rbtools.clients.bazaar import BazaarClient
 from rbtools.clients.errors import (InvalidRevisionSpecError,
@@ -1192,6 +1197,207 @@ def svn_version_set_hash(svn16_hash, svn17_hash):
     return decorator
 
 
+class SVNRepositoryInfoTests(SpyAgency, SCMClientTests):
+    """Unit tests for rbtools.clients.svn.SVNRepositoryInfo."""
+
+    payloads = {
+        'http://localhost:8080/api/': {
+            'mimetype': 'application/vnd.reviewboard.org.root+json',
+            'rsp': {
+                'uri_templates': {},
+                'links': {
+                    'self': {
+                        'href': 'http://localhost:8080/api/',
+                        'method': 'GET',
+                    },
+                    'repositories': {
+                        'href': 'http://localhost:8080/api/repositories/',
+                        'method': 'GET',
+                    },
+                },
+                'stat': 'ok',
+            },
+        },
+        'http://localhost:8080/api/repositories/?tool=Subversion': {
+            'mimetype': 'application/vnd.reviewboard.org.repositories+json',
+            'rsp': {
+                'repositories': [
+                    {
+                        # This one doesn't have a mirror_path, to emulate
+                        # Review Board 1.6.
+                        'id': 1,
+                        'name': 'SVN Repo 1',
+                        'path': 'https://svn1.example.com/',
+                        'links': {
+                            'info': {
+                                'href': ('https://localhost:8080/api/'
+                                         'repositories/1/info/'),
+                                'method': 'GET',
+                            },
+                        },
+                    },
+                    {
+                        'id': 2,
+                        'name': 'SVN Repo 2',
+                        'path': 'https://svn2.example.com/',
+                        'mirror_path': 'svn+ssh://svn2.example.com/',
+                        'links': {
+                            'info': {
+                                'href': ('https://localhost:8080/api/'
+                                         'repositories/2/info/'),
+                                'method': 'GET',
+                            },
+                        },
+                    },
+                ],
+                'links': {
+                    'next': {
+                        'href': ('http://localhost:8080/api/repositories/'
+                                 '?tool=Subversion&page=2'),
+                        'method': 'GET',
+                    },
+                },
+                'total_results': 3,
+                'stat': 'ok',
+            },
+        },
+        'http://localhost:8080/api/repositories/?tool=Subversion&page=2': {
+            'mimetype': 'application/vnd.reviewboard.org.repositories+json',
+            'rsp': {
+                'repositories': [
+                    {
+                        'id': 3,
+                        'name': 'SVN Repo 3',
+                        'path': 'https://svn3.example.com/',
+                        'mirror_path': 'svn+ssh://svn3.example.com/',
+                        'links': {
+                            'info': {
+                                'href': ('https://localhost:8080/api/'
+                                         'repositories/3/info/'),
+                                'method': 'GET',
+                            },
+                        },
+                    },
+                ],
+                'total_results': 3,
+                'stat': 'ok',
+            },
+        },
+        'https://localhost:8080/api/repositories/1/info/': {
+            'mimetype': 'application/vnd.reviewboard.org.repository-info+json',
+            'rsp': {
+                'info': {
+                    'uuid': 'UUID-1',
+                    'url': 'https://svn1.example.com/',
+                    'root_url': 'https://svn1.example.com/',
+                },
+                'stat': 'ok',
+            },
+        },
+        'https://localhost:8080/api/repositories/2/info/': {
+            'mimetype': 'application/vnd.reviewboard.org.repository-info+json',
+            'rsp': {
+                'info': {
+                    'uuid': 'UUID-2',
+                    'url': 'https://svn2.example.com/',
+                    'root_url': 'https://svn2.example.com/',
+                },
+                'stat': 'ok',
+            },
+        },
+        'https://localhost:8080/api/repositories/3/info/': {
+            'mimetype': 'application/vnd.reviewboard.org.repository-info+json',
+            'rsp': {
+                'info': {
+                    'uuid': 'UUID-3',
+                    'url': 'https://svn3.example.com/',
+                    'root_url': 'https://svn3.example.com/',
+                },
+                'stat': 'ok',
+            },
+        },
+    }
+
+    def setUp(self):
+        super(SVNRepositoryInfoTests, self).setUp()
+
+        self.spy_on(urlopen, call_fake=self._urlopen)
+
+        self.api_client = RBClient('http://localhost:8080/')
+        self.root_resource = self.api_client.get_root()
+
+    def test_find_server_repository_info_with_path_match(self):
+        """Testing SVNRepositoryInfo.find_server_repository_info with
+        path matching
+        """
+        info = SVNRepositoryInfo('https://svn1.example.com/', '/', '')
+
+        repo_info = info.find_server_repository_info(self.root_resource)
+        self.assertEqual(repo_info, info)
+        self.assertEqual(repo_info.repository_id, 1)
+
+    def test_find_server_repository_info_with_mirror_path_match(self):
+        """Testing SVNRepositoryInfo.find_server_repository_info with
+        mirror_path matching
+        """
+        info = SVNRepositoryInfo('svn+ssh://svn2.example.com/', '/', '')
+
+        repo_info = info.find_server_repository_info(self.root_resource)
+        self.assertEqual(repo_info, info)
+        self.assertEqual(repo_info.repository_id, 2)
+
+    def test_find_server_repository_info_with_uuid_match(self):
+        """Testing SVNRepositoryInfo.find_server_repository_info with
+        UUID matching
+        """
+        info = SVNRepositoryInfo('svn+ssh://blargle/', '/', 'UUID-3')
+
+        repo_info = info.find_server_repository_info(self.root_resource)
+        self.assertNotEqual(repo_info, info)
+        self.assertEqual(repo_info.repository_id, 3)
+
+    def test_relative_paths(self):
+        """Testing SVNRepositoryInfo._get_relative_path"""
+        info = SVNRepositoryInfo('http://svn.example.com/svn/', '/', '')
+        self.assertEqual(info._get_relative_path('/foo', '/bar'), None)
+        self.assertEqual(info._get_relative_path('/', '/trunk/myproject'),
+                         None)
+        self.assertEqual(info._get_relative_path('/trunk/myproject', '/'),
+                         '/trunk/myproject')
+        self.assertEqual(
+            info._get_relative_path('/trunk/myproject', ''),
+            '/trunk/myproject')
+        self.assertEqual(
+            info._get_relative_path('/trunk/myproject', '/trunk'),
+            '/myproject')
+        self.assertEqual(
+            info._get_relative_path('/trunk/myproject', '/trunk/myproject'),
+            '/')
+
+    def _urlopen(self, request):
+        url = request.get_full_url()
+
+        try:
+            payload = self.payloads[url]
+        except KeyError:
+            return MockResponse(404, {}, json.dumps({
+                'rsp': {
+                    'stat': 'fail',
+                    'err': {
+                        'code': 100,
+                        'msg': 'Object does not exist',
+                    },
+                },
+            }))
+
+        return MockResponse(
+            200,
+            {
+                'Content-Type': payload['mimetype'],
+            },
+            json.dumps(payload['rsp']))
+
+
 class SVNClientTests(SCMClientTests):
     def setUp(self):
         super(SVNClientTests, self).setUp()
@@ -1233,24 +1439,6 @@ class SVNClientTests(SCMClientTests):
 
         self._run_svn(['add', dirname])
 
-    def test_relative_paths(self):
-        """Testing SVNRepositoryInfo._get_relative_path"""
-        info = SVNRepositoryInfo('http://svn.example.com/svn/', '/', '')
-        self.assertEqual(info._get_relative_path('/foo', '/bar'), None)
-        self.assertEqual(info._get_relative_path('/', '/trunk/myproject'),
-                         None)
-        self.assertEqual(info._get_relative_path('/trunk/myproject', '/'),
-                         '/trunk/myproject')
-        self.assertEqual(
-            info._get_relative_path('/trunk/myproject', ''),
-            '/trunk/myproject')
-        self.assertEqual(
-            info._get_relative_path('/trunk/myproject', '/trunk'),
-            '/myproject')
-        self.assertEqual(
-            info._get_relative_path('/trunk/myproject', '/trunk/myproject'),
-            '/')
-
     def test_parse_revision_spec_no_args(self):
         """Testing SVNClient.parse_revision_spec with no specified revisions"""
         revisions = self.client.parse_revision_spec()
