diff --git a/src/app/data-client.spec.ts b/src/app/data-client.spec.ts index 220115521..217cb865a 100644 --- a/src/app/data-client.spec.ts +++ b/src/app/data-client.spec.ts @@ -47,6 +47,8 @@ import { TagsByFilterRequest, TagsByFilterResponse, TagsFilter, + GetLatestTabularDataRequest, + GetLatestTabularDataResponse, } from '../gen/app/data/v1/data_pb'; import { DatasetService } from '../gen/app/dataset/v1/dataset_connect'; import { @@ -830,6 +832,67 @@ describe('DataClient tests', () => { expect(testFilter).toEqual(expectedFilter); }); }); + + describe('getLatestTabularData tests', () => { + const timeCaptured = new Date(2024, 1, 1); + const timeSynced = new Date(2024, 1, 2); + const payload = { key: 'value' }; + + beforeEach(() => { + mockTransport = createRouterTransport(({ service }) => { + service(DataService, { + getLatestTabularData: (req) => { + capReq = req; + return new GetLatestTabularDataResponse({ + timeCaptured: Timestamp.fromDate(timeCaptured), + timeSynced: Timestamp.fromDate(timeSynced), + payload: Struct.fromJson(payload), + }); + }, + }); + }); + }); + + let capReq: GetLatestTabularDataRequest; + + it('get latest tabular data', async () => { + const expectedRequest = new GetLatestTabularDataRequest({ + partId: 'testPartId', + resourceName: 'testResource', + resourceSubtype: 'testSubtype', + methodName: 'testMethod', + }); + + const result = await subject().getLatestTabularData( + 'testPartId', + 'testResource', + 'testSubtype', + 'testMethod' + ); + + expect(capReq).toStrictEqual(expectedRequest); + expect(result).toEqual([timeCaptured, timeSynced, payload]); + }); + + it('returns null when no data available', async () => { + mockTransport = createRouterTransport(({ service }) => { + service(DataService, { + getLatestTabularData: () => { + return new GetLatestTabularDataResponse({}); + }, + }); + }); + + const result = await subject().getLatestTabularData( + 'testPartId', + 'testResource', + 'testSubtype', + 'testMethod' + ); + + expect(result).toBeNull(); + }); + }); }); describe('DatasetClient tests', () => { diff --git a/src/app/data-client.ts b/src/app/data-client.ts index 93a266bc1..c86a0e24f 100644 --- a/src/app/data-client.ts +++ b/src/app/data-client.ts @@ -687,6 +687,44 @@ export class DataClient { return filter; } + + /** + * Gets the most recent tabular data captured from the specified data source, + * as long as it was synced within the last year. + * + * @param partId The ID of the part that owns the data + * @param resourceName The name of the requested resource that captured the + * data + * @param resourceSubtype The subtype of the requested resource that captured + * the data + * @param methodName The data capture method name + * @returns A tuple containing [timeCaptured, timeSynced, payload] or null if + * no data has been synced for the specified resource OR the most recently + * captured data was over a year ago + */ + async getLatestTabularData( + partId: string, + resourceName: string, + resourceSubtype: string, + methodName: string + ): Promise<[Date, Date, Record] | null> { + const resp = await this.dataClient.getLatestTabularData({ + partId, + resourceName, + resourceSubtype, + methodName, + }); + + if (!resp.payload || !resp.timeCaptured || !resp.timeSynced) { + return null; + } + + return [ + resp.timeCaptured.toDate(), + resp.timeSynced.toDate(), + resp.payload.toJson() as Record, + ]; + } } export { type BinaryID, type Order } from '../gen/app/data/v1/data_pb';