Skip to content

Commit

Permalink
feat(server): add location position endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
clemlatz committed May 5, 2024
1 parent 5efd110 commit 06e2b33
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 14 deletions.
2 changes: 2 additions & 0 deletions server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import LocationRepository from './repositories/LocationRepository';
import ShipRepository from './repositories/ShipRepository';
import UserRepository from './repositories/UserRepository';
import LocationController from './controllers/LocationController';
import AstronomyService from './services/AstronomyService';

@Module({
imports: [
Expand All @@ -43,6 +44,7 @@ import LocationController from './controllers/LocationController';
OpenIDConnectService.factory,
AuthenticationGuard,
RegisterNewPilotUsecase,
AstronomyService,
],
})
export class AppModule {}
50 changes: 38 additions & 12 deletions server/src/controllers/LocationController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,25 @@ import { PrismaClient } from '@prisma/client';
import { Response } from 'express';

import LocationController from './LocationController';
import ShipRepository from '../repositories/ShipRepository';
import LocationRepository from '../repositories/LocationRepository';
import EventRepository from '../repositories/EventRepository';
import AuthenticationMethodRepository from '../repositories/AuthenticationMethodRepository';
import AuthenticationGuard from '../guards/AuthenticationGuard';
import Position from '../models/Position';
import Location from '../models/Location';
import AstronomyService from '../services/AstronomyService';

describe('LocationController', () => {
let locationController: LocationController;
let locationRepository: LocationRepository;
let astronomyService: AstronomyService;

beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [LocationController],
providers: [
PrismaClient,
ShipRepository,
LocationRepository,
EventRepository,
AuthenticationGuard,
AuthenticationMethodRepository,
],
providers: [PrismaClient, LocationRepository, AstronomyService],
}).compile();

locationController = app.get<LocationController>(LocationController);
locationRepository = app.get<LocationRepository>(LocationRepository);
astronomyService = app.get<AstronomyService>(AstronomyService);
const locations = [
new Location('earth', 'Earth', new Position(1, 2)),
new Location('moon', 'Moon', new Position(3, 4)),
Expand All @@ -40,6 +32,9 @@ describe('LocationController', () => {
jest
.spyOn(locationRepository, 'getByCode')
.mockImplementation(() => locations[0]);
jest
.spyOn(astronomyService, 'getPositionFor')
.mockResolvedValue(new Position(5, 6));
});

describe('index', () => {
Expand Down Expand Up @@ -101,4 +96,35 @@ describe('LocationController', () => {
});
});
});

describe('getPosition', () => {
describe('when there is a location for given code', () => {
it('returns position for location and date', async () => {
// given
const response = {
json: jest.fn(),
} as unknown as Response;

// when
await locationController.getPosition(
{ code: 'earth' },
{ targetDate: '1556412148000' },
response,
);

// then
expect(astronomyService.getPositionFor).toHaveBeenCalledWith(
'earth',
new Date(parseInt('1556412148000')),
);
expect(response.json).toHaveBeenCalledWith({
data: {
id: 'earth',
type: 'position',
attributes: { x: 5, y: 6 },
},
});
});
});
});
});
27 changes: 25 additions & 2 deletions server/src/controllers/LocationController.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Controller, Get, Param, Res } from '@nestjs/common';
import { Controller, Get, Param, Query, Res } from '@nestjs/common';
import { Response } from 'express';
import LocationRepository from '../repositories/LocationRepository';
import Location from '../models/Location';
import AstronomyService from '../services/AstronomyService';

@Controller()
export default class LocationController {
constructor(private readonly locationRepository: LocationRepository) {}
constructor(
private readonly locationRepository: LocationRepository,
private readonly astronomyService: AstronomyService,
) {}

@Get('api/locations')
async index(@Res() res: Response): Promise<void> {
Expand All @@ -25,6 +29,25 @@ export default class LocationController {
res.json({ data: this._serializeLocation(location) });
}

@Get('api/locations/:code/position')
async getPosition(
@Param() params: { code: string },
@Query() query: { targetDate: string },
@Res() res: Response,
): Promise<void> {
const { x, y } = await this.astronomyService.getPositionFor(
params.code,
new Date(parseInt(query.targetDate)),
);
res.json({
data: {
id: params.code,
type: 'position',
attributes: { x, y },
},
});
}

private _serializeLocation(location: Location) {
return {
id: location.code,
Expand Down

0 comments on commit 06e2b33

Please sign in to comment.