From 9810482eef93c7620549fab73bb3f60159a43d29 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Fri, 27 Mar 2026 08:10:07 -0500 Subject: [PATCH] feat: wip on getAllApps method --- src/models/OnspringClient.ts | 27 ++++++++++++ tests/OnspringClient.spec.ts | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/src/models/OnspringClient.ts b/src/models/OnspringClient.ts index a957bba..c65ab73 100644 --- a/src/models/OnspringClient.ts +++ b/src/models/OnspringClient.ts @@ -111,6 +111,33 @@ export class OnspringClient { return apiResponse.asGetPagedAppsResponseType(); } + /** + * @method getAllApps - Gets an iterable that can be used to page through all. + * @param {PagingRequest} pagingRequest - The paging request that will be used to get the apps. + * @returns + **/ + public async *getAllApps( + pagingRequest: PagingRequest = new PagingRequest(1, 50) + ): AsyncGenerator, void, unknown> { + // TODO: We need to actually honor the page request + // the caller gave us. We will use the page number + // as our starting page number and we will use the + // page size as our page size + for await (const page of this.getAllPagesAsync( + async (pr) => await this.getApps(pr) + )) { + yield page; + } + } + + private async *getAllPagesAsync( + callback: (pagingRequest: PagingRequest) => Promise> + ): AsyncGenerator, void, unknown> { + const pagingRequest = new PagingRequest(1, 50); + const initialResponse = await callback(pagingRequest); + yield initialResponse; + } + /** * @method getAppById - Gets an app by its id. * @param {number} appId - The id of the app to get. diff --git a/tests/OnspringClient.spec.ts b/tests/OnspringClient.spec.ts index 9411448..8d73965 100644 --- a/tests/OnspringClient.spec.ts +++ b/tests/OnspringClient.spec.ts @@ -232,6 +232,85 @@ describe('OnspringClient', function () { }); }); + describe('getAllApps', function () { + it('should be define', function () { + expect(new OnspringClient(baseUrl, apiKey).getAllApps).to.not.be + .undefined; + }); + + it('should be a function', function () { + expect(new OnspringClient(baseUrl, apiKey).getAllApps).to.be.a( + 'function' + ); + }); + + it('should have 0 parameter', function () { + expect(new OnspringClient(baseUrl, apiKey).getAllApps).to.have.lengthOf( + 0 + ); + }); + + it('should return a async generator', function () { + const result = new OnspringClient(baseUrl, apiKey).getAllApps(); + + expect(result).to.have.property(Symbol.asyncIterator); + expect(result[Symbol.asyncIterator]).to.be.a('function'); + + expect(result).to.have.property('next').that.is.a('function'); + expect(result).to.have.property('return').that.is.a('function'); + expect(result).to.have.property('throw').that.is.a('function'); + }); + + it('should return a promise that resolves to an async iterable of paged response of apps when request is successful', async function () { + const client = new OnspringClient(baseUrl, apiKey); + + const mockAxiosClient = axios.create({ + baseURL: baseUrl, + headers: { + 'x-apikey': apiKey, + 'x-api-version': '2', + }, + }); + + sinon.stub(mockAxiosClient, 'get').returns( + Promise.resolve({ + status: 200, + statusText: 'OK', + data: { + pageNumber: 1, + pageSize: 2, + totalPages: 1, + totalRecords: 2, + items: [ + { + href: 'https://api.onspring.dev/Apps/id/1', + id: '1', + name: 'Test App 1', + }, + { + href: 'https://api.onspring.dev/Apps/id/2', + id: '2', + name: 'Test App 2', + }, + ], + }, + headers: {}, + config: {} as InternalAxiosRequestConfig, + } as AxiosResponse) + ); + + sinon.stub(client, '_client' as any).value(mockAxiosClient); + + const collectedPages: Array> = []; + + for await (const page of client.getAllApps()) { + collectedPages.push(page); + } + + expect(collectedPages.length).to.equal(1); + }); + }); + describe('getApps', function () { it('should be defined', function () { expect(new OnspringClient(baseUrl, apiKey).getApps).to.not.be.undefined;