diff --git a/config/vufind/Demo.ini b/config/vufind/Demo.ini
index 40c07261a8da46ec15c6ab131f78524ecdb2af36..b45a6eab8c12f522a1c53e5493574826b5cb71c4 100644
--- a/config/vufind/Demo.ini
+++ b/config/vufind/Demo.ini
@@ -50,8 +50,11 @@ cancelHolds = 50
 cancelILLRequests = 50
 cancelStorageRetrievalRequests = 50
 changePassword = 33
+checkILLRequestBlock = 10
 checkILLRequestIsValid = 10
+checkRequestBlock = 10
 checkRequestIsValid = 10
+checkStorageRetrievalRequestBlock = 10
 checkStorageRetrievalRequestIsValid = 10
 getDefaultRequestGroup = 50
 getHoldDefaultRequiredDate = 50
diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index dd7894766b98b8e0fc39fce14371bd56fed71dee..dc070497b2800758d512d0925d98adef6bf8d11b 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -777,7 +777,8 @@ rfr_id          = vufind.svn.sourceforge.net
 
 ; By specifying your link resolver type, you can allow VuFind to optimize its
 ; OpenURLs for a particular platform.  Current legal values: "sfx", "360link",
-; "EZB", "Redi" or "other" (default is "other" if commented out).
+; "EZB", "Redi," "demo" or "other" (default is "other" if commented out; "demo"
+; generates fake values for use in testing the embed setting below).
 ;resolver        = sfx
 
 ; If you want OpenURL links to open in a new window, set this setting to the
diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index f47a5600d6410466c4c042455bdf3565a244948b..fc1b96b0a6699ca83c38792ae149e8d5d9a17416 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -515,6 +515,9 @@ $config = [
                     'sfx' => 'VuFind\Resolver\Driver\Factory::getSfx',
                     'redi' => 'VuFind\Resolver\Driver\Factory::getRedi',
                 ],
+                'invokables' => [
+                    'demo' => 'VuFind\Resolver\Driver\Demo',
+                ],
                 'aliases' => [
                     'threesixtylink' => '360link',
                 ],
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Demo.php b/module/VuFind/src/VuFind/ILS/Driver/Demo.php
index 44ff959ff76148ddea969036a75b01ed23416647..b64371541b0c8fb833f5261fa68e6a48d9196ed2 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Demo.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Demo.php
@@ -252,6 +252,36 @@ class Demo extends AbstractBase
             ? $this->config['Records']['source'] : DEFAULT_SEARCH_BACKEND;
     }
 
+    /**
+     * Are holds/recalls blocked?
+     *
+     * @return bool
+     */
+    protected function checkRequestBlock()
+    {
+        return $this->isFailing(__METHOD__, 10);
+    }
+
+    /**
+     * Are ILL requests blocked?
+     *
+     * @return bool
+     */
+    protected function checkILLRequestBlock()
+    {
+        return $this->isFailing(__METHOD__, 10);
+    }
+
+    /**
+     * Are storage retrieval requests blocked?
+     *
+     * @return bool
+     */
+    protected function checkStorageRetrievalRequestBlock()
+    {
+        return $this->isFailing(__METHOD__, 10);
+    }
+
     /**
      * Generates a random, fake holding array
      *
@@ -280,16 +310,16 @@ class Demo extends AbstractBase
             'callnumber'   => $this->getFakeCallNum(),
             'duedate'      => '',
             'is_holdable'  => true,
-            'addLink'      => $patron ? rand() % 10 == 0 ? 'block' : true : false,
+            'addLink'      => $patron
+                ? $this->checkRequestBlock() ? 'block' : true : false,
             'level'        => 'copy',
             'storageRetrievalRequest' => 'auto',
             'addStorageRetrievalRequestLink' => $patron
-                ? rand() % 10 == 0 ? 'block' : 'check'
+                ? $this->checkStorageRetrievalRequestBlock() ? 'block' : 'check'
                 : false,
             'ILLRequest'   => 'auto',
             'addILLRequestLink' => $patron
-                ? rand() % 10 == 0 ? 'block' : 'check'
-                : false
+                ? $this->checkILLRequestBlock() ? 'block' : 'check' : false
         ];
     }
 
diff --git a/module/VuFind/src/VuFind/Resolver/Driver/Demo.php b/module/VuFind/src/VuFind/Resolver/Driver/Demo.php
new file mode 100644
index 0000000000000000000000000000000000000000..c04eb7edfc1fc3f4c4cc1d563516c49809b40eb1
--- /dev/null
+++ b/module/VuFind/src/VuFind/Resolver/Driver/Demo.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Demo Link Resolver Driver
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2015.
+ *
+ * last update: 2011-04-13
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  Resolver_Drivers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:link_resolver_drivers Wiki
+ */
+namespace VuFind\Resolver\Driver;
+use DOMDocument, DOMXpath;
+
+/**
+ * Demo Link Resolver Driver
+ *
+ * @category VuFind2
+ * @package  Resolver_Drivers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:link_resolver_drivers Wiki
+ */
+class Demo implements DriverInterface
+{
+    /**
+     * Fetch Links
+     *
+     * Fetches a set of links corresponding to an OpenURL
+     *
+     * @param string $openURL openURL (url-encoded)
+     *
+     * @return string
+     */
+    public function fetchLinks($openURL)
+    {
+        return $openURL;
+    }
+
+    /**
+     * Parse Links
+     *
+     * Parses data returned by a link resolver
+     * and converts it to a standardised format for display
+     *
+     * @param string $data Raw data
+     *
+     * @return array       Array of values
+     */
+    public function parseLinks($data)
+    {
+        return [
+            [
+                'href' => 'https://vufind.org/wiki?' . $data . '#print',
+                'title' => 'Print',
+                'coverage' => 'fake1',
+                'service_type' => 'getHolding',
+                'access' => 'unknown'
+            ],
+            [
+                'href' => 'https://vufind.org/wiki?' . $data . '#electronic',
+                'title' => 'Electronic',
+                'coverage' => 'fake2',
+                'service_type' => 'getFullTxt',
+                'access' => 'open'
+            ],
+        ];
+    }
+}
\ No newline at end of file
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BasicTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BasicTest.php
index d4ca672257653e356c08240e9575e3d5ef6d0a51..972d3113a3defdaa2bbd186063e48210c207dc79 100644
--- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BasicTest.php
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/BasicTest.php
@@ -51,4 +51,32 @@ class BasicTest extends \VuFindTest\Unit\MinkTestCase
         $page = $session->getPage();
         $this->assertTrue(false !== strstr($page->getContent(), 'VuFind'));
     }
+
+    /**
+     * Test that AJAX availability status is working.
+     *
+     * @return void
+     */
+    public function testAjaxStatus()
+    {
+        // Search for a known record:
+        $session = $this->getMinkSession();
+        $session->visit($this->getVuFindUrl() . '/Search/Home');
+        $page = $session->getPage();
+        $this->findCss($page, '.searchForm [name="lookfor"]')
+            ->setValue('id:testsample1');
+        $this->findCss($page, '.btn.btn-primary')->click();
+        $this->snooze();
+
+        // Check for sample driver location/call number in output (this will
+        // only appear after AJAX returns):
+        $this->assertEquals(
+            'A1234.567',
+            $this->findCss($page, '.callnumber')->getText()
+        );
+        $this->assertEquals(
+            '3rd Floor Main Library',
+            $this->findCss($page, '.location')->getText()
+        );
+    }
 }
diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/LinkResolverTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/LinkResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a3461db2d57603cbe83eada7278f7471f57fb0e
--- /dev/null
+++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/LinkResolverTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Mink link resolver test class.
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2016.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  Tests
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://www.vufind.org  Main Page
+ */
+namespace VuFindTest\Mink;
+
+/**
+ * Mink link resolver test class.
+ *
+ * @category VuFind2
+ * @package  Tests
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://www.vufind.org  Main Page
+ */
+class LinkResolverTest extends \VuFindTest\Unit\MinkTestCase
+{
+    /**
+     * Standard setup method.
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        // Give up if we're not running in CI:
+        if (!$this->continuousIntegrationRunning()) {
+            return $this->markTestSkipped('Continuous integration not running.');
+        }
+    }
+
+    /**
+     * Get config.ini override settings for testing ILS functions.
+     *
+     * @return array
+     */
+    public function getConfigIniOverrides()
+    {
+        return [
+            'OpenURL' => [
+                'resolver' => 'demo',
+                'embed' => '1',
+                'url' => 'http://vufind.org/wiki',
+            ]
+        ];
+    }
+
+    public function testPlaceHold()
+    {
+        // Set up configs
+        $this->changeConfigs(
+            [
+                'config' => $this->getConfigIniOverrides(),
+            ]
+        );
+
+        // Search for a known record:
+        $session = $this->getMinkSession();
+        $session->visit($this->getVuFindUrl() . '/Search/Home');
+        $page = $session->getPage();
+        $this->findCss($page, '.searchForm [name="lookfor"]')
+            ->setValue('id:testsample1');
+        $this->findCss($page, '.btn.btn-primary')->click();
+
+        // Click the OpenURL link:
+        $this->findCss($page, '.fulltext')->click();
+        $this->snooze();
+
+        // Confirm that the expected fake demo driver data is there:
+        $electronic = $this->findCss($page, 'a.access-open');
+        $this->assertEquals('Electronic', $electronic->getText());
+        $this->assertEquals('Electronic fake2', $electronic->getParent()->getText());
+        $openUrl = 'url_ver=Z39.88-2004&ctx_ver=Z39.88-2004'
+            . '&ctx_enc=info%3Aofi%2Fenc%3AUTF-8'
+            . '&rfr_id=info%3Asid%2Fvufind.svn.sourceforge.net%3Agenerator'
+            . '&rft.title=Journal+of+rational+emotive+therapy+%3A+the+journal+'
+            . 'of+the+Institute+for+Rational-Emotive+Therapy.'
+            . '&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&rft.creator='
+            . '&rft.pub=The+Institute%2C&rft.format=Journal'
+            . '&rft.language=English&rft.issn=0748-1985';
+        $this->assertEquals(
+            'https://vufind.org/wiki?' . $openUrl . '#electronic',
+            $electronic->getAttribute('href')
+        );
+
+        $print = $this->findCss($page, 'a.access-unknown');
+        $this->assertEquals('Print', $print->getText());
+        $this->assertEquals('Print fake1', $print->getParent()->getText());
+        $this->assertEquals(
+            'https://vufind.org/wiki?' . $openUrl . '#print',
+            $print->getAttribute('href')
+        );
+    }
+}