diff --git a/src/persistence/MCWSPersistenceProvider.js b/src/persistence/MCWSPersistenceProvider.js index 7c3835e..2e4083f 100644 --- a/src/persistence/MCWSPersistenceProvider.js +++ b/src/persistence/MCWSPersistenceProvider.js @@ -49,7 +49,6 @@ export default class MCWSPersistenceProvider extends BaseMCWSPersistenceProvider try { await persistenceNamespace.opaqueFile(key).create(model); - return true; } catch (error) { console.warn('MCWSPersistneceProvider:create', error); @@ -78,7 +77,7 @@ export default class MCWSPersistenceProvider extends BaseMCWSPersistenceProvider } catch (error) { console.warn('MCWSPersistneceProvider:update', error); - return; + return false; } } diff --git a/src/persistence/test/MCWSNamespaceModelProviderSpec.js b/src/persistence/test/MCWSNamespaceModelProviderSpec.js index 4b6640a..761bcdd 100644 --- a/src/persistence/test/MCWSNamespaceModelProviderSpec.js +++ b/src/persistence/test/MCWSNamespaceModelProviderSpec.js @@ -1,138 +1,246 @@ -/*global define,describe,beforeEach,jasmine,Promise,it,expect*/ -define([ - // '../src/MCWSNamespaceModelProvider' -], function ( - // MCWSNamespaceModelProvider -) { - 'use strict'; - - xdescribe('MCWSNamespaceModelProvider', function () { - var namespaceService, + +import MCWSUserContainerProvider from '../MCWSUserContainerProvider'; +import MCWSPersistenceProvider from '../MCWSPersistenceProvider'; +import mcws from '../../services/mcws/mcws'; + +describe('MCWS Providers', () => { + let openmct; + let someNamespace; + let anotherNamespace; + let personalContainerNamespace; + let personalNamespace; + let namespaces; + let userContainerProvider; + let persistenceProvider; + + beforeEach(() => { + openmct = { + user: { + getCurrentUser: () => Promise.resolve({ id: 'myUser' }) + } + }; + + someNamespace = { + id: 'some-namespace:root', + key: 'some-namespace', + name: 'Some Namespace', + url: '/some/namespace/url' + }; + anotherNamespace = { + id: 'another-namespace:root', + key: 'another-namespace', + name: 'Another Namespace', + url: '/another/namespace/url', + location: 'some-namespace:root' + }; + personalContainerNamespace = { + id: 'personal', + key: 'personal', + name: 'personal', + url: '/some/personal/namespace', + containsNamespaces: true, + childTemplate: { + id: 'personal-{username}:root', + key: 'personal-{username}', + name: '{username}', + url: '/some/personal/namespace/{username}' + } + }; + personalNamespace = { + id: 'personal-myUser:root', + key: 'personal-myUser', + name: 'myUser', + url: '/some/personal/namespace/myUser', + location: 'personal' + }; + + namespaces = [ someNamespace, anotherNamespace, personalContainerNamespace, - personalNamespace, - namespaces, - provider; - - beforeEach(function () { - namespaceService = jasmine.createSpyObj( - 'namespaceService', - [ - 'getPersistenceNamespaces', - 'getContainedNamespaces' - ] + personalNamespace + ]; + + const roots = [personalContainerNamespace]; + userContainerProvider = new MCWSUserContainerProvider(openmct, roots); + persistenceProvider = new MCWSPersistenceProvider(openmct, roots); + + // Mock mcws service calls + spyOn(userContainerProvider, 'getPersistenceNamespaces') + .and.returnValue(Promise.resolve(namespaces)); + spyOn(userContainerProvider, 'getContainedNamespaces') + .and.callFake((namespace) => { + if (namespace.id === 'personal') { + return Promise.resolve([personalNamespace]); + } + return Promise.resolve([]); + }); + }); + + describe('MCWSUserContainerProvider', () => { + it('gets container model with contained namespaces', async () => { + const identifier = { + namespace: 'personal', + key: 'container' + }; + const model = await userContainerProvider.get(identifier); + + expect(model.type).toBe('folder'); + expect(model.composition).toEqual([{ key: 'root', namespace: 'personal-myUser' }]); + expect(model.location).toBe('ROOT'); + }); + }); + + describe('MCWSPersistenceProvider', () => { + let mcwsNamespace; + + beforeEach(() => { + // Mock mcws namespace operations + const fileOps = { + read: () => Promise.resolve({ + json: () => Promise.resolve({ + type: 'folder', + name: 'Test Object' + }) + }), + create: jasmine.createSpy('create').and.returnValue(Promise.resolve(true)), + replace: jasmine.createSpy('replace').and.returnValue(Promise.resolve(true)) + }; + mcwsNamespace = { + opaqueFile: () => fileOps + }; + + spyOn(persistenceProvider, 'getPersistenceNamespaces') + .and.returnValue(Promise.resolve(namespaces)); + // Mock the private getNamespace method through the mcws import + spyOn(mcws, 'namespace').and.returnValue(mcwsNamespace); + }); + + it('gets persisted objects', async () => { + const identifier = { + namespace: 'personal-myUser', + key: 'some-object' + }; + const result = await persistenceProvider.get(identifier); + + expect(result).toBeDefined(); + expect(result.type).toBe('folder'); + expect(result.name).toBe('Test Object'); + expect(result.identifier).toEqual(identifier); + }); + + it('handles abort signal when getting objects', async () => { + const identifier = { + namespace: 'personal-myUser', + key: 'some-object' + }; + const abortSignal = new AbortController().signal; + + await persistenceProvider.get(identifier, abortSignal); + + expect(mcws.namespace).toHaveBeenCalledWith( + jasmine.any(String), + { signal: abortSignal } ); + }); - someNamespace = { - id: 'some-namespace:root', - key: 'some-namespace', - name: 'Some Namespace', - url: '/some/namespace/url' + it('creates new objects', async () => { + const domainObject = { + identifier: { + namespace: 'some-namespace', + key: 'new-object' + }, + type: 'folder', + name: 'New Folder' }; - anotherNamespace = { - id: 'another-namespace:root', - key: 'another-namespace', - name: 'Another Namespace', - url: '/another/namespace/url', - location: 'some-namespace:root' + + const success = await persistenceProvider.create(domainObject); + const expectedModel = { + type: 'folder', + name: 'New Folder' }; - personalContainerNamespace = { - id: 'personal', - key: 'personal', - name: 'personal', - url: '/some/personal/namespace' + + expect(success).toBe(true); + expect(mcwsNamespace.opaqueFile('new-object').create) + .toHaveBeenCalledWith(expectedModel); + }); + + it('updates existing objects', async () => { + const domainObject = { + identifier: { + namespace: 'some-namespace', + key: 'existing-object' + }, + type: 'folder', + name: 'Updated Folder' }; - personalNamespace = { - id: 'personal-myUser:root', - key: 'personal-myUser}', - name: 'myUser', - url: '/some/personal/namespace/myUser', - location: 'personal' + + const success = await persistenceProvider.update(domainObject); + const expectedModel = { + type: 'folder', + name: 'Updated Folder' }; - namespaces = [ - someNamespace, - anotherNamespace, - personalContainerNamespace, - personalNamespace - ]; + expect(success).toBe(true); + expect(mcwsNamespace.opaqueFile('existing-object').replace) + .toHaveBeenCalledWith(expectedModel); + }); - namespaceService - .getPersistenceNamespaces - .and.returnValue(Promise.resolve(namespaces)); + it('handles errors during get operation', async () => { + const errorNamespace = { + opaqueFile: () => ({ + read: () => Promise.reject(new Error('Network Error')) + }) + }; + mcws.namespace.and.returnValue(errorNamespace); - namespaceService - .getContainedNamespaces - .and.callFake(function (namespace) { - if (namespace.id === 'personal') { - return Promise.resolve([personalNamespace]); - } - return Promise.resolve([]); - }); + const identifier = { + namespace: 'personal-myUser', + key: 'error-object' + }; + const result = await persistenceProvider.get(identifier); - provider = new MCWSNamespaceModelProvider(namespaceService); + expect(result).toBeUndefined(); }); - describe('getModels', function () { - var someNamespaceModel, - anotherNamespaceModel, - personalContainerNamespaceModel, - personalNamespaceModel, - allNamespaceModels; - - beforeEach(function (done) { - provider - .getModels([ - 'some-namespace:root', - 'another-namespace:root', - 'personal', - 'personal-myUser:root' - ]) - .then(function (models) { - someNamespaceModel = models['some-namespace:root']; - anotherNamespaceModel = - models['another-namespace:root']; - personalContainerNamespaceModel = models.personal; - personalNamespaceModel = models['personal-myUser:root']; - allNamespaceModels = [ - someNamespaceModel, - anotherNamespaceModel, - personalContainerNamespaceModel, - personalNamespaceModel - ]; - }) - .then(done); - }); + it('handles errors during create operation', async () => { + const errorNamespace = { + opaqueFile: () => ({ + create: () => Promise.reject(new Error('Creation Error')) + }) + }; + mcws.namespace.and.returnValue(errorNamespace); - it('sets type to folder', function () { - allNamespaceModels.forEach(function (namespaceModel) { - expect(namespaceModel.type).toBe('folder'); - }); - }); + const domainObject = { + identifier: { + namespace: 'personal-myUser', + key: 'error-object' + }, + type: 'folder' + }; + const success = await persistenceProvider.create(domainObject); - it('uses location specified in namespace definition', function () { - expect(anotherNamespaceModel.location) - .toBe('some-namespace:root'); - expect(personalNamespaceModel.location) - .toBe('personal'); - }); + expect(success).toBe(false); + }); - it('sets default location if not specified', function () { - expect(someNamespaceModel.location).toBe('ROOT'); - expect(personalContainerNamespaceModel.location).toBe('ROOT'); - }); + it('handles errors during update operation', async () => { + const errorNamespace = { + opaqueFile: () => ({ + replace: () => Promise.reject(new Error('Update Error')) + }) + }; + mcws.namespace.and.returnValue(errorNamespace); - it('sets composition', function () { - expect(someNamespaceModel.composition) - .toEqual(jasmine.any(Array)); - expect(anotherNamespaceModel.composition) - .toEqual(jasmine.any(Array)); - expect(personalContainerNamespaceModel.composition) - .toEqual(['personal-myUser:root']); - expect(personalNamespaceModel.composition) - .toEqual(jasmine.any(Array)); - }); + const domainObject = { + identifier: { + namespace: 'personal-myUser', + key: 'error-object' + }, + type: 'folder' + }; + const success = await persistenceProvider.update(domainObject); + + expect(success).toBe(false); }); }); }); diff --git a/src/product-status/DataProductRowSpec.js b/src/product-status/DataProductRowSpec.js index 42bfbc0..51488ba 100644 --- a/src/product-status/DataProductRowSpec.js +++ b/src/product-status/DataProductRowSpec.js @@ -1,206 +1,198 @@ -/*global define,describe,beforeEach,it,expect*/ +import DataProductRow from './DataProductRow'; -define([ - './DataProductRow' -], function ( - DataProductRow -) { - 'use strict'; +describe('The Data Product Row', function () { + let dataProductRow; + let columns; + let objectKeyString; + let limitEvaluator; + let rowId; + let startMessage; + let partReceivedMessage; + let completeMessage; - describe('The Data Product Row', function () { - let dataProductRow; - let columns; - let objectKeyString; - let limitEvaluator; - let rowId; - let startMessage; - let partReceivedMessage; - let completeMessage; - - beforeEach(function () { - columns = []; - objectKeyString = 'test-object'; - limitEvaluator = { - evaluate: function () {return {}} - }; - rowId = 'test-row-id'; - startMessage = { - "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", - "session_host":"host", - "apid":"424", - "total_parts":"0", - "session_id":"36", - "record_type":"product_started", - "part_number":"0", - "event_time":"2019-259T17:06:54.691", - "vcid":"32" - }; - partReceivedMessage = { - "creation_time":"", - "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", - "dvt_coarse":"457586851", - "ground_status":"UNKNOWN", - "session_host":"host", - "ert":"2019-259T17:06:54.590", - "dvt_fine":"19880", - "apid":"424", - "total_parts":"0", - "session_id":"36", - "scet":"2014-183T15:39:04.687010296", - "lst":"", - "version":"", - "file_size":"0", - "record_type":"product_part_received", - "command_number":"0", - "unique_name":"products\/McamRThumbnail\/McamRThumbnail_0457586851-19880", - "seq_version":"0", - "checksum":"0", - "part_number":"0", - "sclk":"0457586851.30334", - "seq_id":"0", - "event_time":"2019-259T17:06:54.691", - "vcid":"32" - }; - completeMessage = { - "creation_time":"2019-259T17:06:57.800", - "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", - "dvt_coarse":"457586851", - "ground_status":"COMPLETE_CHECKSUM_PASS", - "session_host":"host", - "ert":"2019-259T17:06:54.590", - "dvt_fine":"19880", - "apid":"424", - "total_parts":"20", - "session_id":"36", - "scet":"2014-183T15:39:04.687010296", - "lst":"", - "version":"", - "file_size":"192819", - "record_type":"complete_product", - "command_number":"2", - "unique_name":"complete_product_unique_name", - "seq_version":"0", - "checksum":"33862", - "sclk":"0457586851.30334", - "seq_id":"0", - "event_time":"2019-259T17:06:54.691", - "vcid":"32" - } - }); + beforeEach(function () { + columns = []; + objectKeyString = 'test-object'; + limitEvaluator = { + evaluate: function () {return {}} + }; + rowId = 'test-row-id'; + startMessage = { + "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", + "session_host":"host", + "apid":"424", + "total_parts":"0", + "session_id":"36", + "record_type":"product_started", + "part_number":"0", + "event_time":"2019-259T17:06:54.691", + "vcid":"32" + }; + partReceivedMessage = { + "creation_time":"", + "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", + "dvt_coarse":"457586851", + "ground_status":"UNKNOWN", + "session_host":"host", + "ert":"2019-259T17:06:54.590", + "dvt_fine":"19880", + "apid":"424", + "total_parts":"0", + "session_id":"36", + "scet":"2014-183T15:39:04.687010296", + "lst":"", + "version":"", + "file_size":"0", + "record_type":"product_part_received", + "command_number":"0", + "unique_name":"products\/McamRThumbnail\/McamRThumbnail_0457586851-19880", + "seq_version":"0", + "checksum":"0", + "part_number":"0", + "sclk":"0457586851.30334", + "seq_id":"0", + "event_time":"2019-259T17:06:54.691", + "vcid":"32" + }; + completeMessage = { + "creation_time":"2019-259T17:06:57.800", + "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", + "dvt_coarse":"457586851", + "ground_status":"COMPLETE_CHECKSUM_PASS", + "session_host":"host", + "ert":"2019-259T17:06:54.590", + "dvt_fine":"19880", + "apid":"424", + "total_parts":"20", + "session_id":"36", + "scet":"2014-183T15:39:04.687010296", + "lst":"", + "version":"", + "file_size":"192819", + "record_type":"complete_product", + "command_number":"2", + "unique_name":"complete_product_unique_name", + "seq_version":"0", + "checksum":"33862", + "sclk":"0457586851.30334", + "seq_id":"0", + "event_time":"2019-259T17:06:54.691", + "vcid":"32" + } + }); - it('Sets received parts to 0 when start message received', function () { - dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); - expect(dataProductRow.datum.parts_received).toBe(0); - }); + it('Sets received parts to 0 when start message received', function () { + dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); + expect(dataProductRow.datum.parts_received).toBe(0); + }); - it('Increments part count when product part message received', function () { - dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); - expect(dataProductRow.datum.parts_received).toBe(0); - dataProductRow.update(partReceivedMessage); - expect(dataProductRow.datum.parts_received).toBe(1); - }); + it('Increments part count when product part message received', function () { + dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); + expect(dataProductRow.datum.parts_received).toBe(0); + dataProductRow.update(partReceivedMessage); + expect(dataProductRow.datum.parts_received).toBe(1); + }); - it('Replaces content of in progress rows with info from new message', function () { - const secondPartReceived = { - "creation_time":"", - "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", - "dvt_coarse":"457586851", - "ground_status":"UNKNOWN", - "session_host":"host", - "ert":"2019-259T17:06:54.590", - "dvt_fine":"19880", - "apid":"424", - "total_parts":"0", - "session_id":"36", - "scet":"2014-183T15:39:04.687010296", - "lst":"", - "version":"", - "file_size":"0", - "record_type":"product_part_received", - "command_number":"0", - "unique_name":"a_different_unique_name", - "seq_version":"0", - "checksum":"1234", - "part_number":"2", - "sclk":"0457586851.30334", - "seq_id":"0", - "event_time":"2019-259T17:06:54.691", - "vcid":"32" - }; + it('Replaces content of in progress rows with info from new message', function () { + const secondPartReceived = { + "creation_time":"", + "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", + "dvt_coarse":"457586851", + "ground_status":"UNKNOWN", + "session_host":"host", + "ert":"2019-259T17:06:54.590", + "dvt_fine":"19880", + "apid":"424", + "total_parts":"0", + "session_id":"36", + "scet":"2014-183T15:39:04.687010296", + "lst":"", + "version":"", + "file_size":"0", + "record_type":"product_part_received", + "command_number":"0", + "unique_name":"a_different_unique_name", + "seq_version":"0", + "checksum":"1234", + "part_number":"2", + "sclk":"0457586851.30334", + "seq_id":"0", + "event_time":"2019-259T17:06:54.691", + "vcid":"32" + }; - dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); + dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); - dataProductRow.update(partReceivedMessage); - expect(dataProductRow.datum["unique_name"]).toEqual("products\/McamRThumbnail\/McamRThumbnail_0457586851-19880"); - expect(dataProductRow.datum["checksum"]).toEqual("0"); - expect(dataProductRow.datum["part_number"]).toEqual("0"); + dataProductRow.update(partReceivedMessage); + expect(dataProductRow.datum["unique_name"]).toEqual("products\/McamRThumbnail\/McamRThumbnail_0457586851-19880"); + expect(dataProductRow.datum["checksum"]).toEqual("0"); + expect(dataProductRow.datum["part_number"]).toEqual("0"); - dataProductRow.update(secondPartReceived); - expect(dataProductRow.datum["unique_name"]).toEqual("a_different_unique_name"); - expect(dataProductRow.datum["checksum"]).toEqual("1234"); - expect(dataProductRow.datum["part_number"]).toEqual("2"); - expect(false); - }); + dataProductRow.update(secondPartReceived); + expect(dataProductRow.datum["unique_name"]).toEqual("a_different_unique_name"); + expect(dataProductRow.datum["checksum"]).toEqual("1234"); + expect(dataProductRow.datum["part_number"]).toEqual("2"); + expect(false); + }); - it('Does not replace content of complete rows with in progress rows', function () { - dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); - dataProductRow.update(partReceivedMessage); - expect(dataProductRow.datum["unique_name"]).toEqual("products\/McamRThumbnail\/McamRThumbnail_0457586851-19880"); - expect(dataProductRow.datum["checksum"]).toEqual("0"); - expect(dataProductRow.datum["part_number"]).toEqual("0"); - - dataProductRow.update(completeMessage); - expect(dataProductRow.datum["unique_name"]).toEqual("complete_product_unique_name"); - expect(dataProductRow.datum["checksum"]).toEqual("33862"); - expect(dataProductRow.datum["part_number"]).toBeUndefined(); + it('Does not replace content of complete rows with in progress rows', function () { + dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); + dataProductRow.update(partReceivedMessage); + expect(dataProductRow.datum["unique_name"]).toEqual("products\/McamRThumbnail\/McamRThumbnail_0457586851-19880"); + expect(dataProductRow.datum["checksum"]).toEqual("0"); + expect(dataProductRow.datum["part_number"]).toEqual("0"); + + dataProductRow.update(completeMessage); + expect(dataProductRow.datum["unique_name"]).toEqual("complete_product_unique_name"); + expect(dataProductRow.datum["checksum"]).toEqual("33862"); + expect(dataProductRow.datum["part_number"]).toBeUndefined(); - dataProductRow.update(partReceivedMessage); - expect(dataProductRow.datum["unique_name"]).toEqual("complete_product_unique_name"); - expect(dataProductRow.datum["checksum"]).toEqual("33862"); - expect(dataProductRow.datum["part_number"]).toBeUndefined(); - }); + dataProductRow.update(partReceivedMessage); + expect(dataProductRow.datum["unique_name"]).toEqual("complete_product_unique_name"); + expect(dataProductRow.datum["checksum"]).toEqual("33862"); + expect(dataProductRow.datum["part_number"]).toBeUndefined(); + }); - it('Does replace content of complete rows with complete rows', function () { - const aDifferentCompleteMessage = { - "creation_time":"2019-259T17:06:57.800", - "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", - "dvt_coarse":"457586851", - "ground_status":"COMPLETE_CHECKSUM_PASS", - "session_host":"host", - "ert":"2019-259T17:06:54.590", - "dvt_fine":"19880", - "apid":"424", - "total_parts":"20", - "session_id":"36", - "scet":"2014-183T15:39:04.687010296", - "lst":"", - "version":"", - "file_size":"192819", - "record_type":"complete_product", - "command_number":"2", - "unique_name":"a_different_complete_product_unique_name", - "seq_version":"0", - "checksum":"54321", - "sclk":"0457586851.30334", - "seq_id":"0", - "event_time":"2019-259T17:07:57.800", - "vcid":"32" - } - dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); - dataProductRow.update(partReceivedMessage); - expect(dataProductRow.datum["unique_name"]).toEqual("products\/McamRThumbnail\/McamRThumbnail_0457586851-19880"); - expect(dataProductRow.datum["checksum"]).toEqual("0"); - expect(dataProductRow.datum["part_number"]).toEqual("0"); - - dataProductRow.update(completeMessage); - expect(dataProductRow.datum["unique_name"]).toEqual("complete_product_unique_name"); - expect(dataProductRow.datum["checksum"]).toEqual("33862"); - expect(dataProductRow.datum["event_time"]).toEqual("2019-259T17:06:54.691"); + it('Does replace content of complete rows with complete rows', function () { + const aDifferentCompleteMessage = { + "creation_time":"2019-259T17:06:57.800", + "transaction_id":"McamRThumbnail\/McamRThumbnail_0457586851-19880", + "dvt_coarse":"457586851", + "ground_status":"COMPLETE_CHECKSUM_PASS", + "session_host":"host", + "ert":"2019-259T17:06:54.590", + "dvt_fine":"19880", + "apid":"424", + "total_parts":"20", + "session_id":"36", + "scet":"2014-183T15:39:04.687010296", + "lst":"", + "version":"", + "file_size":"192819", + "record_type":"complete_product", + "command_number":"2", + "unique_name":"a_different_complete_product_unique_name", + "seq_version":"0", + "checksum":"54321", + "sclk":"0457586851.30334", + "seq_id":"0", + "event_time":"2019-259T17:07:57.800", + "vcid":"32" + } + dataProductRow = new DataProductRow(startMessage, columns, objectKeyString, limitEvaluator, rowId); + dataProductRow.update(partReceivedMessage); + expect(dataProductRow.datum["unique_name"]).toEqual("products\/McamRThumbnail\/McamRThumbnail_0457586851-19880"); + expect(dataProductRow.datum["checksum"]).toEqual("0"); + expect(dataProductRow.datum["part_number"]).toEqual("0"); + + dataProductRow.update(completeMessage); + expect(dataProductRow.datum["unique_name"]).toEqual("complete_product_unique_name"); + expect(dataProductRow.datum["checksum"]).toEqual("33862"); + expect(dataProductRow.datum["event_time"]).toEqual("2019-259T17:06:54.691"); - dataProductRow.update(aDifferentCompleteMessage); - expect(dataProductRow.datum["unique_name"]).toEqual("a_different_complete_product_unique_name"); - expect(dataProductRow.datum["checksum"]).toEqual("54321"); - expect(dataProductRow.datum["event_time"]).toEqual("2019-259T17:07:57.800") - }); + dataProductRow.update(aDifferentCompleteMessage); + expect(dataProductRow.datum["unique_name"]).toEqual("a_different_complete_product_unique_name"); + expect(dataProductRow.datum["checksum"]).toEqual("54321"); + expect(dataProductRow.datum["event_time"]).toEqual("2019-259T17:07:57.800") }); });