Use relative pathname instead of static pathname for local replication (#1120)

diff --git a/app/addons/replication/__tests__/api.tests.js b/app/addons/replication/__tests__/api.tests.js
index 4b39507..92d1d9d 100644
--- a/app/addons/replication/__tests__/api.tests.js
+++ b/app/addons/replication/__tests__/api.tests.js
@@ -81,6 +81,22 @@
       assert.ok(/my%2Fdb/.test(source.url));
     });
 
+    it('returns local source with auth info and encoded when use relative url', () => {
+      const localSource = 'my/db';
+      const source = getSource({
+        replicationSource: Constants.REPLICATION_SOURCE.LOCAL,
+        localSource,
+        sourceAuth: {
+          username: 'the-user',
+          password: 'password'
+        },
+        sourceAuthType: Constants.REPLICATION_AUTH_METHOD.BASIC
+      }, {origin: 'http://dev:6767', pathname:'/db/_utils'});
+
+      assert.deepEqual(source.headers, {Authorization:"Basic dGhlLXVzZXI6cGFzc3dvcmQ="});
+      assert.ok(/\/db\/my%2Fdb/.test(source.url));
+    });
+
     it('returns remote source url and auth header', () => {
       const source = getSource({
         replicationSource: Constants.REPLICATION_SOURCE.REMOTE,
@@ -184,6 +200,21 @@
       assert.ok(/my-existing%2Fdb/.test(target.url));
     });
 
+    it('returns existing local database even with relative urls', () => {
+      const target = getTarget({
+        replicationTarget: Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE,
+        localTarget: 'my-existing/db',
+        targetAuth: {
+          username: 'the-user',
+          password: 'password'
+        },
+        targetAuthType: Constants.REPLICATION_AUTH_METHOD.BASIC
+      }, {origin:'http://dev:6767', pathname:'/db/_utils'});
+
+      assert.deepEqual(target.headers, {Authorization:"Basic dGhlLXVzZXI6cGFzc3dvcmQ="});
+      assert.ok(/my-existing%2Fdb/.test(target.url));
+    });
+
     it('returns new local database', () => {
       const target = getTarget({
         replicationTarget: Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE,
diff --git a/app/addons/replication/__tests__/helpers.tests.js b/app/addons/replication/__tests__/helpers.tests.js
index 0703f39..20b1715 100644
--- a/app/addons/replication/__tests__/helpers.tests.js
+++ b/app/addons/replication/__tests__/helpers.tests.js
@@ -15,11 +15,11 @@
 describe('Replication Helpers - getDatabaseLabel', () => {
 
   it('returns database name for string', () => {
-    const db = 'http://tester:testerpass@127.0.0.1/fancy/db/name';
+    const db = 'http://tester:testerpass@127.0.0.1/db/fancy%2Fdb%2Fname';
 
     const res = helpers.getDatabaseLabel(db);
 
-    expect(res).toBe('fancy/db/name');
+    expect(res).toBe('fancy%2Fdb%2Fname');
   });
 
   it('returns database name for object', () => {
diff --git a/app/addons/replication/api.js b/app/addons/replication/api.js
index 2ec00f8..b092e15 100644
--- a/app/addons/replication/api.js
+++ b/app/addons/replication/api.js
@@ -100,11 +100,14 @@
   sourceAuthType,
   sourceAuth
 },
-{origin} = window.location) => {
+{origin, pathname} = window.location) => {
 
   const source = {};
   if (replicationSource === Constants.REPLICATION_SOURCE.LOCAL) {
-    source.url = encodeFullUrl(`${origin}/${localSource}`);
+    const encodedLocalTarget = encodeURIComponent(localSource);
+
+    const root = Helpers.getRootUrl({origin, pathname});
+    source.url = `${root}${encodedLocalTarget}`;
   } else {
     source.url = encodeFullUrl(removeCredentialsFromUrl(remoteSource));
   }
@@ -121,7 +124,7 @@
   targetAuth
 },
 //this allows us to mock out window.location for our tests
-{origin} = window.location) => {
+{origin, pathname} = window.location) => {
 
   const target = {};
   if (replicationTarget === Constants.REPLICATION_TARGET.NEW_REMOTE_DATABASE ||
@@ -129,7 +132,8 @@
     target.url = encodeFullUrl(removeCredentialsFromUrl(remoteTarget));
   } else {
     const encodedLocalTarget = encodeURIComponent(localTarget);
-    target.url = `${origin}/${encodedLocalTarget}`;
+    const root = Helpers.getRootUrl({origin, pathname});
+    target.url = `${root}${encodedLocalTarget}`;
   }
 
   setCredentials(target, targetAuthType, targetAuth);
diff --git a/app/addons/replication/components/common-table.js b/app/addons/replication/components/common-table.js
index 1365817..f12b382 100644
--- a/app/addons/replication/components/common-table.js
+++ b/app/addons/replication/components/common-table.js
@@ -16,22 +16,33 @@
 import moment from 'moment';
 import {ErrorModal} from './modals';
 import {removeCredentialsFromUrl} from '../api';
+import Helpers from '../../../helpers';
+
+const getDbNameFromUrl = (urlObj, root) => {
+  try {
+    const urlWithoutDb = new URL(root);
+    const dbName = urlObj.pathname.substring(urlWithoutDb.pathname.length);
+    return encodeURIComponent(dbName);
+  } catch (e) {
+    return '';
+  }
+};
 
 export const formatUrl = (url) => {
   let urlObj;
   let encoded;
   try {
     urlObj = new URL(removeCredentialsFromUrl(url));
-    encoded = encodeURIComponent(urlObj.pathname.slice(1));
   } catch (e) {
     return '';
   }
-
+  const root = Helpers.getRootUrl();
+  encoded = getDbNameFromUrl(urlObj, root);
   if (url.indexOf(window.location.hostname) > -1) {
     return (
       <span>
-        {urlObj.origin + '/'}
-        <a href={`#/database/${encoded}/_all_docs`}>{urlObj.pathname.slice(1)}</a>
+        {root}
+        <a href={`#/database/${encoded}/_all_docs`}>{decodeURIComponent(encoded)}</a>
       </span>
     );
   }
diff --git a/app/addons/replication/helpers.js b/app/addons/replication/helpers.js
index 52472fa..c436e02 100644
--- a/app/addons/replication/helpers.js
+++ b/app/addons/replication/helpers.js
@@ -14,7 +14,8 @@
 
 const getDatabaseLabel = db => {
   const dbString = (_.isString(db)) ? db.trim().replace(/\/$/, '') : db.url;
-  return (new URL(dbString)).pathname.slice(1);
+  const pathName = (new URL(dbString)).pathname.slice(1);
+  return pathName.split("/").pop();
 };
 
 export default {
diff --git a/app/helpers.js b/app/helpers.js
index ed25130..53bef2a 100644
--- a/app/helpers.js
+++ b/app/helpers.js
@@ -78,6 +78,10 @@
   return app.host + endpointRoute;
 };
 
+Helpers.getRootUrl = ({origin, pathname} = window.location) => {
+  return url.resolve(origin + pathname, app.host);
+};
+
 Helpers.getUUID = function (count = 1) {
   const url = Helpers.getServerUrl(`/_uuids?count=${count}`);
   return get(url);