Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Commit

Permalink
fix; SQS integration fixes (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSlimvReal authored Feb 9, 2024
1 parent 6986bb0 commit 1b740a5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 22 deletions.
6 changes: 4 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
SENTRY_DSN=
PORT=
DATABASE_URL=https://dev.aam-digital.net/db
QUERY_URL=http://localhost:3002
DATABASE_URL=http://127.0.0.1:5984
COUCHDB_ADMIN=admin
COUCHDB_PASSWORD=admin
QUERY_URL=http://127.0.0.1:4984
SCHEMA_CONFIG_ID=_design/sqlite:config
2 changes: 2 additions & 0 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ COPY --from=builder /app/dist ./dist
ENV SENTRY_DSN=""
ENV PORT=""
ENV DATABASE_URL=""
ENV COUCHDB_ADMIN=""
ENV COUCHDB_PASSWORD=""
ENV QUERY_URL=""

CMD ["node", "dist/main"]
Expand Down
56 changes: 39 additions & 17 deletions src/app.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AppController } from './app.controller';
import { Test, TestingModule } from '@nestjs/testing';
import { of, throwError } from 'rxjs';
import { firstValueFrom, of, throwError } from 'rxjs';
import { HttpService } from '@nestjs/axios';
import { BadRequestException, HttpException, HttpStatus } from '@nestjs/common';
import { SqlReport } from './sql-report';
Expand All @@ -13,6 +13,7 @@ describe('AppController', () => {
const dbUrl = 'database:3000';
const queryUrl = 'query:3000';
const schemaConfigId = '_design/sqlite:config';
const adminAuth = { username: 'admin', password: 'adminPW' };

beforeEach(async () => {
mockHttp = {
Expand All @@ -28,6 +29,10 @@ describe('AppController', () => {
return queryUrl;
case 'SCHEMA_CONFIG_ID':
return schemaConfigId;
case 'COUCHDB_ADMIN':
return adminAuth.username;
case 'COUCHDB_PASSWORD':
return adminAuth.password;
default:
throw Error('missing mock value for ' + key);
}
Expand Down Expand Up @@ -67,35 +72,50 @@ describe('AppController', () => {
expect(mockHttp.post).toHaveBeenCalledWith(
`${queryUrl}/app/${schemaConfigId}`,
{ query: report.aggregationDefinitions[0] },
{ auth: adminAuth },
);
expect(res).toEqual(queryResult);

done();
});
});

it('should add dates as args to query request', (done) => {
it('should add dates as args to query request if "?" is used', async () => {
const report: SqlReport = {
mode: 'sql',
aggregationDefinitions: [
'SELECT * FROM Note WHERE e.date BETWEEN ? AND ?',
],
aggregationDefinitions: [],
};
mockHttp.get.mockReturnValue(of({ data: report }));
const body: QueryBody = { from: '2023-01-01', to: '2024-01-01' };

controller
.queryData('ReportConfig:some-id', 'app', 'valid token', body)
.subscribe(() => {
expect(mockHttp.post).toHaveBeenCalledWith(
`${queryUrl}/app/${schemaConfigId}`,
{
query: report.aggregationDefinitions[0],
args: [body.from, body.to],
},
);
done();
});
// No "?" in query
report.aggregationDefinitions = ['SELECT * FROM Note'];
await firstValueFrom(
controller.queryData('ReportConfig:some-id', 'app', 'valid token', body),
);
expect(mockHttp.post).toHaveBeenCalledWith(
`${queryUrl}/app/${schemaConfigId}`,
{
query: report.aggregationDefinitions[0],
},
{ auth: adminAuth },
);

// two "?" in query
report.aggregationDefinitions = [
'SELECT * FROM Note WHERE e.date BETWEEN ? AND ?',
];
await firstValueFrom(
controller.queryData('ReportConfig:some-id', 'app', 'valid token', body),
);
expect(mockHttp.post).toHaveBeenCalledWith(
`${queryUrl}/app/${schemaConfigId}`,
{
query: report.aggregationDefinitions[0],
args: [body.from, body.to],
},
{ auth: adminAuth },
);
});

it('should concatenate the result of multiple SELECT queries', (done) => {
Expand All @@ -116,10 +136,12 @@ describe('AppController', () => {
expect(mockHttp.post).toHaveBeenCalledWith(
`${queryUrl}/app/${schemaConfigId}`,
{ query: report.aggregationDefinitions[0] },
{ auth: adminAuth },
);
expect(mockHttp.post).toHaveBeenCalledWith(
`${queryUrl}/app/${schemaConfigId}`,
{ query: report.aggregationDefinitions[1] },
{ auth: adminAuth },
);
expect(res).toEqual([...firstResult, ...secondResult]);

Expand Down
10 changes: 7 additions & 3 deletions src/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ export class AppController {
private dbUrl = this.configService.get('DATABASE_URL');
private queryUrl = this.configService.get('QUERY_URL');
private schemaDocId = this.configService.get('SCHEMA_CONFIG_ID');
private couchAdmin = this.configService.get('COUCHDB_ADMIN');
private couchPassword = this.configService.get('COUCHDB_PASSWORD');
constructor(
private http: HttpService,
private configService: ConfigService,
) {}

// TODO also support cookie auth? Not really required with Keycloak
@ApiOperation({
description: `Get the results for the report with the given ID. User needs 'read' access for the requested report entity.`,
})
Expand Down Expand Up @@ -78,11 +79,14 @@ export class AppController {

private getQueryResult(query: string, args: QueryBody, db: string) {
const data: SqsRequest = { query: query };
if (args?.from && args?.to) {
// There needs to be the same amount of "?" in the query as elements in "args"
if (args?.from && args?.to && query.match(/\?/g)?.length === 2) {
data.args = [args.from, args.to];
}
return this.http
.post<any[]>(`${this.queryUrl}/${db}/${this.schemaDocId}`, data)
.post<any[]>(`${this.queryUrl}/${db}/${this.schemaDocId}`, data, {
auth: { username: this.couchAdmin, password: this.couchPassword },
})
.pipe(map(({ data }) => data));
}
}
Expand Down

0 comments on commit 1b740a5

Please sign in to comment.