mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
fix(kobo): support GET request on analytics gettests endpoint
Kobo devices send GET requests to /v1/analytics/gettests during sync checks. Previously only POST was handled, causing 404 errors during subsequent syncs. Closes #697
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import { RequestMethod } from '@nestjs/common';
|
||||
import { METHOD_METADATA, PATH_METADATA } from '@nestjs/common/constants';
|
||||
|
||||
import { KoboDeviceController } from './kobo-device.controller';
|
||||
|
||||
function makeReply() {
|
||||
@@ -160,14 +163,34 @@ describe('KoboDeviceController', () => {
|
||||
expect(thumbnailService.serveThumbnail).toHaveBeenCalledWith(11, 420, undefined, reply);
|
||||
});
|
||||
|
||||
it('returns static payload endpoints and analytics keys', async () => {
|
||||
it('returns static payload endpoints and ingests analytics events', async () => {
|
||||
expect(controller.affiliate()).toEqual({});
|
||||
expect(controller.remainingBookSeries()).toEqual({ TotalResultCount: 0, SearchResults: [] });
|
||||
expect(controller.productNextRead()).toEqual([]);
|
||||
analyticsService.ingest.mockResolvedValue(undefined);
|
||||
await expect(controller.analyticsEvent({ Events: [] }, { id: 3 } as never, { deviceToken: 't' } as never)).resolves.toEqual({});
|
||||
expect(analyticsService.ingest).toHaveBeenCalledWith({ Events: [] }, { id: 3 }, { deviceToken: 't' });
|
||||
expect(controller.getTests()).toEqual({ Result: 'Success', TestKey: expect.any(String) });
|
||||
});
|
||||
|
||||
it('registers GET and POST handlers for the advertised gettests endpoint', () => {
|
||||
expect(Reflect.getMetadata(PATH_METADATA, KoboDeviceController.prototype.getTests)).toBe('v1/analytics/gettests');
|
||||
expect(Reflect.getMetadata(METHOD_METADATA, KoboDeviceController.prototype.getTests)).toBe(RequestMethod.GET);
|
||||
expect(Reflect.getMetadata(PATH_METADATA, KoboDeviceController.prototype.postGetTests)).toBe('v1/analytics/gettests');
|
||||
expect(Reflect.getMetadata(METHOD_METADATA, KoboDeviceController.prototype.postGetTests)).toBe(RequestMethod.POST);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['GET', () => controller.getTests()],
|
||||
['POST', () => controller.postGetTests()],
|
||||
])('returns a Kobo-compatible success payload for %s gettests requests', (_method, request) => {
|
||||
const response = request();
|
||||
|
||||
expect(response).toEqual({
|
||||
Result: 'Success',
|
||||
TestKey: expect.stringMatching(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/),
|
||||
Tests: {},
|
||||
});
|
||||
expect(proxyService.forward).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns {} when analytics ingest throws', async () => {
|
||||
|
||||
@@ -119,10 +119,16 @@ export class KoboDeviceController {
|
||||
return [];
|
||||
}
|
||||
|
||||
@Post('v1/analytics/gettests')
|
||||
@Get('v1/analytics/gettests')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
getTests() {
|
||||
return { Result: 'Success', TestKey: randomUUID() };
|
||||
return this.buildGetTestsResponse();
|
||||
}
|
||||
|
||||
@Post('v1/analytics/gettests')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
postGetTests() {
|
||||
return this.buildGetTestsResponse();
|
||||
}
|
||||
|
||||
@Post('v1/analytics/event')
|
||||
@@ -143,6 +149,10 @@ export class KoboDeviceController {
|
||||
await this.proxyService.forward(req, reply, device.deviceToken);
|
||||
}
|
||||
|
||||
private buildGetTestsResponse() {
|
||||
return { Result: 'Success', TestKey: randomUUID(), Tests: {} };
|
||||
}
|
||||
|
||||
private async serveThumbnailOrProxy(
|
||||
bookId: string,
|
||||
ifNoneMatch: string | undefined,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"totalRoutes": 367,
|
||||
"totalRoutes": 368,
|
||||
"byPermission": {
|
||||
"(none)": 164,
|
||||
"(none)": 165,
|
||||
"Permission.ManageMetadataConfig": 32,
|
||||
"Permission.EmailSend": 30,
|
||||
"Permission.LibraryEditMetadata": 31,
|
||||
|
||||
@@ -195,6 +195,18 @@
|
||||
"file": "server/src/modules/kobo/kobo-device.controller.ts",
|
||||
"className": "KoboDeviceController",
|
||||
"methodName": "getTests",
|
||||
"httpMethod": "GET",
|
||||
"path": "/kobo/:deviceToken/v1/analytics/gettests",
|
||||
"permissions": [],
|
||||
"libraryAccess": [],
|
||||
"isPublic": true,
|
||||
"allowDefault": false,
|
||||
"useGuards": ["KoboTokenGuard"]
|
||||
},
|
||||
{
|
||||
"file": "server/src/modules/kobo/kobo-device.controller.ts",
|
||||
"className": "KoboDeviceController",
|
||||
"methodName": "postGetTests",
|
||||
"httpMethod": "POST",
|
||||
"path": "/kobo/:deviceToken/v1/analytics/gettests",
|
||||
"permissions": [],
|
||||
|
||||
Reference in New Issue
Block a user