github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/kat/src/test/corda/assets/authored-private-structured.ts (about)

     1  // Copyright © 2021 Kaleido, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  import { app, mockEventStreamWebSocket } from '../../common';
    16  import { v4 as uuidV4 } from 'uuid';
    17  import { testContent } from '../../samples';
    18  import nock from 'nock';
    19  import request from 'supertest';
    20  import assert from 'assert';
    21  import { IDBAssetDefinition, IDBAssetInstance} from '../../../lib/interfaces';
    22  import * as utils from '../../../lib/utils';
    23  
    24  export const testAssetsAuthoredPrivateStructured = () => {
    25  
    26  describe('Assets: authored - structured', async () => {
    27  
    28    let assetDefinitionID = uuidV4();
    29    const assetDefinitionName = 'authored - private - structured';
    30    const timestamp = new Date();
    31  
    32    describe('Create asset definition', () => {
    33  
    34      it('Checks that the asset definition can be added', async () => {
    35  
    36        nock('https://apigateway.kaleido.io')
    37          .post('/createAssetDefinition')
    38          .reply(200);
    39  
    40        nock('https://ipfs.kaleido.io')
    41          .post('/api/v0/add')
    42          .reply(200, { Hash: 'Qmf71q7zspRmzvH6yVhkrpWCnK54rvxyj6XSTJ5tgBiZfV' });
    43  
    44        const result = await request(app)
    45          .post('/api/v1/assets/definitions')
    46          .send({
    47            name: assetDefinitionName,
    48            author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
    49            assetDefinitionID,
    50            isContentPrivate: true,
    51            isContentUnique: true,
    52            contentSchema: testContent.schema.object
    53          })
    54          .expect(200);
    55        assert.deepStrictEqual(result.body.status, 'submitted');
    56  
    57        const getAssetDefinitionsResponse = await request(app)
    58          .get('/api/v1/assets/definitions')
    59          .expect(200);
    60        const assetDefinition = getAssetDefinitionsResponse.body.find((assetDefinition: IDBAssetDefinition) => assetDefinition.name === 'authored - private - structured');
    61        assert.strictEqual(assetDefinition.assetDefinitionID, assetDefinitionID);
    62        assert.strictEqual(assetDefinition.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US');
    63        assert.strictEqual(assetDefinition.isContentPrivate, true);
    64        assert.strictEqual(assetDefinition.isContentUnique, true);
    65        assert.deepStrictEqual(assetDefinition.contentSchema, testContent.schema.object);
    66        assert.strictEqual(assetDefinition.name, 'authored - private - structured');
    67        assert.strictEqual(typeof assetDefinition.submitted, 'number');
    68      });
    69  
    70    });
    71  
    72    describe('Asset instances', async () => {
    73  
    74      let assetInstanceID: string;
    75  
    76      describe('Asset instances - argument validation', async () => {
    77        it('Attempting to add an asset instance without specifying participants should raise an error', async () => {
    78          const result = await request(app)
    79            .post(`/api/v1/assets/${assetDefinitionID}`)
    80            .send({
    81              content: {
    82                my_content_string: 'test sample content string',
    83                my_content_number: 124,
    84                my_content_boolean: false
    85              },
    86              author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US'
    87            })
    88            .expect(400);
    89          assert.deepStrictEqual(result.body, { error: 'Missing asset participants' });
    90        });
    91  
    92        it('Attempting to add an asset instance without specifying participants should raise an error', async () => {
    93          const result = await request(app)
    94            .post(`/api/v1/assets/${assetDefinitionID}`)
    95            .send({
    96              content: {
    97                my_content_string: 'test sample content string',
    98                my_content_number: 124,
    99                my_content_boolean: false
   100              },
   101              author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
   102              participants: ['CN=Node of node3 for env1, O=Kaleido, L=Raleigh, C=US']
   103            })
   104            .expect(400);
   105          assert.deepStrictEqual(result.body, { error: `One or more participants are not registered` });
   106        });
   107  
   108        it('Attempting to set an asset instance property without specifying key should raise an error', async () => {
   109          const result = await request(app)
   110            .put(`/api/v1/assets/some-asset-def-id/some-asset-id`)
   111            .send({
   112              action: 'set-property',
   113              author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
   114            })
   115            .expect(400);
   116          assert.deepStrictEqual(result.body, { error: `Missing asset property key` });
   117        });
   118  
   119        it('Attempting to set an asset instance property without specifying value should raise an error', async () => {
   120          const result = await request(app)
   121            .put(`/api/v1/assets/some-asset-def-id/some-asset-id`)
   122            .send({
   123              action: 'set-property',
   124              key: 'key',
   125              author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
   126            })
   127            .expect(400);
   128          assert.deepStrictEqual(result.body, { error: `Missing asset property value` });
   129        });
   130      });
   131  
   132      it('Checks that an asset instance can be created', async () => {
   133  
   134        nock('https://apigateway.kaleido.io')
   135          .post('/createAssetInstance')
   136          .reply(200);
   137  
   138        const result = await request(app)
   139          .post(`/api/v1/assets/${assetDefinitionID}`)
   140          .send({
   141            author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
   142            content: testContent.sample.object,
   143            participants: ['CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US']
   144          })
   145          .expect(200);
   146        assert.deepStrictEqual(result.body.status, 'submitted');
   147        assetInstanceID = result.body.assetInstanceID;
   148  
   149        const getAssetInstancesResponse = await request(app)
   150          .get(`/api/v1/assets/${assetDefinitionID}`)
   151          .expect(200);
   152        const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID);
   153        assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US');
   154        assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID);
   155        assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256);
   156        assert.deepStrictEqual(assetInstance.content, testContent.sample.object);
   157        assert.strictEqual(typeof assetInstance.submitted, 'number');
   158  
   159        const getAssetInstanceResponse = await request(app)
   160          .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`)
   161          .expect(200);
   162        assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body);
   163  
   164      });
   165  
   166      it('Checks that the event stream notification for confirming the asset instance creation is handled', async () => {
   167        const eventPromise = new Promise<void>((resolve) => {
   168          mockEventStreamWebSocket.once('send', message => {
   169            assert.strictEqual(message, '{"type":"ack","topic":"dev"}');
   170            resolve();
   171          })
   172        });
   173        const assetData: any = {
   174          assetDefinitionID: assetDefinitionID,
   175          author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
   176          assetInstanceID: assetInstanceID,
   177          contentHash: testContent.sample.docExchangeSha256,
   178          participants: ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US']
   179        };
   180        mockEventStreamWebSocket.emit('message', JSON.stringify([{
   181          signature: utils.contractEventSignaturesCorda.ASSET_INSTANCE_CREATED,
   182          data: {data: assetData},
   183          stateRef: {
   184            txhash: "25D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE",
   185            index: 0
   186          },
   187          subId: "sb-f5abe54b-53fb-4f63-8236-f3a8a6bc1c60",
   188          recordedTime: timestamp.toISOString(),
   189          consumedTime: null
   190        }]));
   191        await eventPromise;
   192      });
   193  
   194      it('Checks that the asset instance is confirmed', async () => {
   195        const getAssetInstancesResponse = await request(app)
   196          .get(`/api/v1/assets/${assetDefinitionID}`)
   197          .expect(200);
   198        const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID);
   199        assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US');
   200        assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID);
   201        assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256);
   202        assert.deepStrictEqual(assetInstance.content, testContent.sample.object);
   203        assert.strictEqual(assetInstance.timestamp, timestamp.getTime());
   204        assert.strictEqual(typeof assetInstance.submitted, 'number');
   205        assert.strictEqual(assetInstance.transactionHash, '25D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE');
   206        assert.deepStrictEqual(assetInstance.participants, ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US'])
   207        const getAssetInstanceResponse = await request(app)
   208          .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`)
   209          .expect(200);
   210        assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body);
   211      });
   212  
   213      it('Checks that the asset instance property can be set', async () => {
   214        nock('https://apigateway.kaleido.io')
   215        .post('/setAssetInstanceProperty')
   216        .reply(200);
   217  
   218        const result = await request(app)
   219          .put(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`)
   220          .send({
   221            author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
   222            action: 'set-property',
   223            key: 'key1',
   224            value: 'value1'
   225           })
   226          .expect(200);
   227        assert.deepStrictEqual(result.body.status, 'submitted');
   228  
   229        const getAssetInstancesResponse = await request(app)
   230          .get(`/api/v1/assets/${assetDefinitionID}`)
   231          .expect(200);
   232        const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID);
   233        assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US');
   234        assert.strictEqual(assetInstance.properties[assetInstance.author]['key1'].value, 'value1');
   235        assert.strictEqual(typeof assetInstance.properties[assetInstance.author]['key1'].submitted, 'number');
   236        const getAssetInstanceResponse = await request(app)
   237          .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`)
   238          .expect(200);
   239        assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body);
   240  
   241      });
   242  
   243      it('Checks that the event stream notification for confirming the asset instance set property is handled', async () => {
   244        const eventPromise = new Promise<void>((resolve) => {
   245          mockEventStreamWebSocket.once('send', message => {
   246            assert.strictEqual(message, '{"type":"ack","topic":"dev"}');
   247            resolve();
   248          })
   249        });
   250        const assetData: any = {
   251          assetDefinitionID: assetDefinitionID,
   252          author: 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US',
   253          assetInstanceID: assetInstanceID,
   254          key: 'key1',
   255          value: 'value1',
   256          participants: ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US']
   257        };
   258        mockEventStreamWebSocket.emit('message', JSON.stringify([{
   259          signature: utils.contractEventSignaturesCorda.ASSET_PROPERTY_SET,
   260          data: {data: assetData},
   261          stateRef: {
   262            txhash: "35D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE",
   263            index: 0
   264          },
   265          subId: "sb-f5abe54b-53fb-4f63-8236-f3a8a6bc1c60",
   266          recordedTime: timestamp.toISOString(),
   267          consumedTime: null
   268        }]));
   269        await eventPromise;
   270      });
   271  
   272      it('Checks that the asset instance property set is confirmed', async () => {
   273        const getAssetInstancesResponse = await request(app)
   274          .get(`/api/v1/assets/${assetDefinitionID}`)
   275          .expect(200);
   276        const assetInstance = getAssetInstancesResponse.body.find((assetInstance: IDBAssetInstance) => assetInstance.assetInstanceID === assetInstanceID);
   277        assert.strictEqual(assetInstance.author, 'CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US');
   278        assert.strictEqual(assetInstance.assetDefinitionID, assetDefinitionID);
   279        assert.strictEqual(assetInstance.contentHash, testContent.sample.docExchangeSha256);
   280        assert.deepStrictEqual(assetInstance.content, testContent.sample.object);
   281        assert.strictEqual(assetInstance.timestamp, timestamp.getTime());
   282        assert.strictEqual(typeof assetInstance.submitted, 'number');
   283        assert.strictEqual(assetInstance.transactionHash, '25D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE');
   284        assert.deepStrictEqual(assetInstance.participants, ['CN=Node of node1 for env1, O=Kaleido, L=Raleigh, C=US', 'CN=Node of node2 for env1, O=Kaleido, L=Raleigh, C=US'])
   285        assert.strictEqual(assetInstance.properties[assetInstance.author]['key1'].value, 'value1');
   286        assert.strictEqual(typeof assetInstance.properties[assetInstance.author]['key1'].submitted, 'number');
   287        assert.strictEqual(assetInstance.properties[assetInstance.author]['key1'].history[assetInstance.timestamp].transactionHash, '35D867CC5D19AB40AE46E6262F3C274A6B772D68A0AA522F4C5A96196EAF5FCE');
   288  
   289        const getAssetInstanceResponse = await request(app)
   290          .get(`/api/v1/assets/${assetDefinitionID}/${assetInstanceID}`)
   291          .expect(200);
   292        assert.deepStrictEqual(assetInstance, getAssetInstanceResponse.body);
   293      });
   294  
   295    });
   296  
   297  });
   298  };