Skip to content

Commit

Permalink
Handle lat/lon correctly. Relates to #23
Browse files Browse the repository at this point in the history
  • Loading branch information
pwalsh committed Dec 8, 2021
1 parent 51c1673 commit fb8cf67
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 14 deletions.
8 changes: 6 additions & 2 deletions src/core/open311/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ interface IServiceRequestAttributes {
createdAt: Date;
updatedAt: Date;
images: string[];
lat: number;
lon: number
}

export const toOpen311Service = (service: IServiceAttributes): IOpen311Service => ({
Expand All @@ -42,8 +44,8 @@ export const toOpen311ServiceRequest = (serviceRequest: IServiceRequestAttribute
requested_datetime: serviceRequest.createdAt.toISOString(),
updated_datetime: serviceRequest.updatedAt.toISOString(),
address_id: '',
lat: 0,
long: 0,
lat: serviceRequest.lat,
long: serviceRequest.lon,
zipcode: '',
media_url: serviceRequest.images?.length > 0 ? serviceRequest.images[0] : '',
});
Expand All @@ -57,4 +59,6 @@ export const toGovflowServiceRequest = (payload: IOpen311ServiceRequestCreatePay
lastName: payload.last_name,
phone: payload.phone,
email: payload.email,
lat: payload.lat as number,
lon: payload.long as number
});
4 changes: 1 addition & 3 deletions src/core/open311/repositories.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { injectable } from 'inversify';
import { IOpen311ServiceRepository, IOpen311ServiceRequestRepository, QueryParamsAll } from '../../types';
import { toOpen311Service, toOpen311ServiceRequest, toGovflowServiceRequest } from './helpers';
import { toGovflowServiceRequest, toOpen311Service, toOpen311ServiceRequest } from './helpers';
import { IOpen311Service, IOpen311ServiceRequest, IOpen311ServiceRequestCreatePayload } from './types';

@injectable()
Expand Down Expand Up @@ -40,9 +40,7 @@ export class Open311ServiceRequestRepository implements IOpen311ServiceRequestRe
/* eslint-disable */
//@ts-ignore
const { ServiceRequest } = this.models;

const govflowServiceRequest = toGovflowServiceRequest(data as unknown as IOpen311ServiceRequestCreatePayload);

const record = await ServiceRequest.create(govflowServiceRequest);
return toOpen311ServiceRequest(record);
/* eslint-enable @typescript-eslint/ban-ts-comment */
Expand Down
15 changes: 9 additions & 6 deletions src/core/service-requests/models.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { DataTypes } from 'sequelize';
import validator from 'validator';
import { ModelDefinition } from '../../types';
Expand Down Expand Up @@ -44,9 +43,13 @@ export const ServiceRequestModel: ModelDefinition = {
allowNull: true,
type: DataTypes.STRING,
},
geometry: {
allowNull: true,
type: DataTypes.ARRAY(DataTypes.STRING(2)),
lat: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
lon: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
images: {
allowNull: true,
Expand Down Expand Up @@ -121,8 +124,8 @@ export const ServiceRequestModel: ModelDefinition = {
],
validate: {
oneOfAddressOrGeometry() {
if ((this.geometry === null) && (this.address === null) && (this.address_id === null)) {
throw new Error('A Service Request requires one of geometry, address, or address_id.');
if ((this.lat || this.lon === null) && (this.address === null) && (this.address_id === null)) {
throw new Error('A Service Request requires one of a lat/lon pair, address, or address_id.');
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/logging/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const logger = winston.createLogger({
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple(),
level: 'warning',
}));
}

Expand Down
26 changes: 26 additions & 0 deletions src/migrations/03_servicerequest_geometry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { QueryInterface } from 'sequelize';
import { DataTypes } from 'sequelize';

export async function up({ context: queryInterface }: Record<string, QueryInterface>): Promise<void> {
await queryInterface.removeColumn('ServiceRequest', 'geometry');
await queryInterface.addColumn(
'ServiceRequest',
'lat',
{ allowNull: false, type: DataTypes.FLOAT, defaultValue: 0 }
);
await queryInterface.addColumn(
'ServiceRequest',
'lon',
{ allowNull: false, type: DataTypes.FLOAT, defaultValue: 0 }
);
}

export async function down({ context: queryInterface }: Record<string, QueryInterface>): Promise<void> {
await queryInterface.removeColumn('ServiceRequest', 'lat');
await queryInterface.removeColumn('ServiceRequest', 'lon');
await queryInterface.addColumn(
'ServiceRequest',
'geometry',
{ allowNull: false, type: DataTypes.ARRAY(DataTypes.STRING(2)), }
);
}
4 changes: 3 additions & 1 deletion src/tools/fake-data-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function makeService(options: Record<string, Record<string, unknown>>) {

function makeServiceRequest(options: Record<string, Record<string, unknown>>) {
const dates = [
new Date('2021-11-01T00:00:00.000Z'),
new Date('2021-12-01T00:00:00.000Z'),
new Date('2021-11-01T00:00:00.000Z'),
new Date('2021-10-01T00:00:00.000Z'),
new Date('2021-09-01T00:00:00.000Z'),
Expand All @@ -61,6 +61,8 @@ function makeServiceRequest(options: Record<string, Record<string, unknown>>) {
id: faker.datatype.uuid(),
description: faker.lorem.sentences(5),
address: faker.address.streetAddress(),
lat: faker.datatype.number({ precision: 0.0001 }),
lon: faker.datatype.number({ precision: 0.0001 }),
images: [faker.image.imageUrl(), faker.image.imageUrl()],
status: faker.helpers.randomize(['inbox', 'todo', 'doing', 'blocked', 'done']),
firstName: faker.name.firstName(),
Expand Down
4 changes: 3 additions & 1 deletion test/fixtures/open311.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export const validServiceRequestData = [
'description': 'There is garbage all over the sidewalk.',
'address': 'Sunset Boulevarde, Hollywood',
'email': 'email@example.com',
'phone': '+1 972 609 9933'
'phone': '+1 972 609 9933',
'lat': -238.008,
'long': 327.4830
},
]

Expand Down
21 changes: 20 additions & 1 deletion test/test-endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import faker from 'faker';
import _ from 'lodash';
import { createApp } from '../src';
import makeTestData, { writeTestDataToDatabase } from '../src/tools/fake-data-generator';
import { validServiceRequestData } from './fixtures/open311';

chai.use(chaiHttp);

Expand Down Expand Up @@ -228,7 +229,7 @@ describe('Hit all API endpoints', function () {

it('should GET all service requests filtered by dateTo for a jurisdiction', async function () {
let jurisdictionId = testData.jurisdictions[0].id;
const dateTo = '2021-11-01T00:00:00.000Z';
const dateTo = '2021-12-01T00:00:00.000Z';
try {
const res = await chai.request(app).get(`/service-requests/?jurisdictionId=${jurisdictionId}&dateTo=${dateTo}`)
chai.assert.equal(res.status, 200);
Expand Down Expand Up @@ -428,6 +429,24 @@ describe('Hit all API endpoints', function () {
}
});

it('should POST a service request as Open311 for a jurisdiction', async function () {
let jurisdiction_id = testData.jurisdictions[0].id;
let jurisdiction_services = _.filter(testData.services, { jurisdictionId: jurisdiction_id });
let service_code = jurisdiction_services[0].id;
let serviceRequestData = _.cloneDeep(validServiceRequestData[0]);
// @ts-ignore
serviceRequestData.jurisdiction_id = jurisdiction_id;
// @ts-ignore
serviceRequestData.service_code = service_code;
try {
const res = await chai.request(app).post(`/open311/v2/requests.json`).send(serviceRequestData)
chai.assert.equal(res.status, 200);
chai.assert.equal(res.body.data.service_code, serviceRequestData.service_code);
} catch (error) {
throw error;
}
});

it('should return 501 not implemented error for GET one service as Open311 for a jurisdiction in JSON format', async function () {
let jurisdictionId = testData.jurisdictions[0].id;
try {
Expand Down
2 changes: 2 additions & 0 deletions test/test-repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ describe('Verify Core Repositories.', function () {
chai.assert(record);
chai.assert.equal(record.description, serviceRequestData.description);
chai.assert.equal(record.service_code, serviceRequestData.service_code);
chai.assert.equal(record.lat, serviceRequestData.lat);
chai.assert.equal(record.long, serviceRequestData.long);
}
});

Expand Down

0 comments on commit fb8cf67

Please sign in to comment.