Merge "js: Add debug string to blessing object"
diff --git a/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js b/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js
index 34bd36f..dddfbf4 100644
--- a/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js
+++ b/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js
@@ -139,6 +139,11 @@
 };
     
       
+Controller.prototype.blessingsDebugString = function(ctx, serverCall, handle) {
+  throw new Error('Method BlessingsDebugString not implemented');
+};
+    
+      
 Controller.prototype.bless = function(ctx, serverCall, publicKey, blessingHandle, extension, caveat) {
   throw new Error('Method Bless not implemented');
 };
@@ -279,6 +284,27 @@
     
       
     {
+    name: 'BlessingsDebugString',
+    doc: "// BlessingsDebugString gets a string useful for debugging blessings.",
+    inArgs: [{
+      name: 'handle',
+      doc: "",
+      type: new principal.BlessingsHandle()._type
+    },
+    ],
+    outArgs: [{
+      name: '',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: []
+  },
+    
+      
+    {
     name: 'Bless',
     doc: "// Bless binds extensions of blessings held by this principal to\n// another principal (represented by its public key).",
     inArgs: [{
diff --git a/src/security/blessings.js b/src/security/blessings.js
index 0fdd20d..22e4544 100644
--- a/src/security/blessings.js
+++ b/src/security/blessings.js
@@ -59,6 +59,15 @@
   };
 };
 
+/**
+ * Get a string that describes this blessings object.
+ * @return {Promise} A promise to a string describing the blessings.
+ * @private
+ */
+Blessings.prototype._debugString = function(ctx) {
+  return this._controller.blessingsDebugString(ctx, this._id);
+};
+
 Blessings.prototype.convertToJsBlessings = function() {
   return new JsBlessings({
     handle: this._id,
diff --git a/src/security/principal.js b/src/security/principal.js
index a0bdc52..ef149b7 100644
--- a/src/security/principal.js
+++ b/src/security/principal.js
@@ -114,11 +114,12 @@
 
   var caveats = args.slice(2);
 
-  this._controller.blessSelf.call(this._controller, ctx, name, caveats)
+  var controller = this._controller;
+  controller.blessSelf.call(this._controller, ctx, name, caveats)
   .then(function(res) {
     var publicKey = res[0];
     var handle = res[1];
-    def.resolve(new Blessings(handle, publicKey, this._controller));
+    def.resolve(new Blessings(handle, publicKey, controller));
   }).catch(function(err) {
     def.reject(err);
   });
diff --git a/test/integration/test-bless.js b/test/integration/test-bless.js
index fd059f3..cf0bc73 100644
--- a/test/integration/test-bless.js
+++ b/test/integration/test-bless.js
@@ -11,6 +11,15 @@
 var Blessings = require('../../src/security/blessings');
 var SharedContextKeys = require('../../src/runtime/shared-context-keys');
 
+function validateBlessings(t, blessings) {
+  t.ok(blessings instanceof Blessings, 'Blessings have correct type');
+  t.ok(typeof blessings._id === 'number' && blessings._id !== 0,
+    'Blessing has non-zero id');
+  t.ok(typeof blessings.publicKey === 'string' && blessings.publicKey !== '',
+    'Blessing has public key');
+  t.ok(blessings._controller, 'Blessing object has controller attached');
+}
+
 test('Test bless self without Caveat', function(t) {
   var rt;
   vanadium.init(config, function(err, runtime) {
@@ -22,7 +31,7 @@
 
     runtime.principal.blessSelf(runtime.getContext(), 'ext')
     .then(function(blessings) {
-      t.ok(blessings instanceof Blessings, 'Got blessings');
+      validateBlessings(t, blessings);
       rt.close(t.end);
     }).catch(function(err) {
       t.error(err);
@@ -44,7 +53,7 @@
       caveats.createExpiryCaveat(new Date()),
       function(err, blessings) {
       t.error(err);
-      t.ok(blessings instanceof Blessings, 'Got blessings');
+      validateBlessings(t, blessings);
       rt.close(t.end);
     });
   });
@@ -86,9 +95,9 @@
       var remoteKey = secCall.remoteBlessings.publicKey;
       rt.principal.bless(ctx, remoteKey, secCall.localBlessings,
        'ext', caveats.createExpiryCaveat(new Date(Date.now() - 1000)),
-       caveats.createConstCaveat(true), function(err, blessing) {
+       caveats.createConstCaveat(true), function(err, blessings) {
          t.notOk(err, 'No error expected during bless');
-         t.ok(blessing instanceof Blessings, 'Got blessing');
+         validateBlessings(t, blessings);
          cb();
        });
     }
@@ -210,3 +219,25 @@
     });
   });
 });
+
+test('Test fetching blessing debug string', function(t) {
+  var rt;
+  vanadium.init(config, function(err, runtime) {
+    if (err) {
+      t.end(err);
+    }
+
+    rt = runtime;
+
+    runtime.principal.blessSelf(runtime.getContext(), 'blessedname')
+    .then(function(blessings) {
+      return blessings._debugString(runtime.getContext());
+    }).then(function(debugString) {
+      t.ok(debugString === 'blessedname', 'Got blessed name as debug string');
+      rt.close(t.end);
+    }).catch(function(err) {
+      t.error(err);
+      rt.close(t.end);
+    });
+  });
+});