Skip to content

Commit c8edbd1

Browse files
committed
Finishing coverage on contacts
1 parent 64d4796 commit c8edbd1

File tree

8 files changed

+200
-211
lines changed

8 files changed

+200
-211
lines changed

README.md

Lines changed: 1 addition & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Build Status](https://travis-ci.org/CodeForBaltimore/Bmore-Responsive.svg?branch=master)](https://travis-ci.org/CodeForBaltimore/Bmore-Responsive) [![codecov](https://codecov.io/gh/CodeForBaltimore/Bmore-Responsive/branch/master/graph/badge.svg)](https://codecov.io/gh/CodeForBaltimore/Bmore-Responsive)
1+
[![Build Status](https://travis-ci.org/CodeForBaltimore/Bmore-Responsive.svg?branch=master)](https://travis-ci.org/CodeForBaltimore/Bmore-Responsive) [![codecov](https://codecov.io/gh/CodeForBaltimore/Bmore-Responsive/branch/master/graph/badge.svg)](https://codecov.io/gh/CodeForBaltimore/Bmore-Responsive) [![GitHub release](https://img.shields.io/github/release/Naereen/StrapDown.js.svg)](https://github.com/CodeForBaltimore/Bmore-Responsive/releases) [![Open Source Love svg1](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/)
22

33
# Bmore Responsive
44
A simple, flexible API to support emergency response coordination. Sample use cases include:
@@ -15,154 +15,6 @@ Bmore-Responsive provides the following primary features via a secure REST API:
1515
- User account and role management to enable secure authentication and authorization
1616
- Export of any data via CSV
1717

18-
<<TODO: Conclude with reference to QuickStart and/or Wiki>>
19-
20-
21-
22-
23-
## --- Old README content below, Refactored version above ----
24-
25-
<!-- TOC -->
26-
27-
- [Bmore Responsive](#bmore-responsive)
28-
- [--- Old README content below, Refactored version above ----](#----old-readme-content-below-refactored-version-above-----)
29-
- [Setup](#setup)
30-
- [Node and Express setup](#node-and-express-setup)
31-
- [Environment variables](#environment-variables)
32-
- [Example .env](#example-env)
33-
- [PostgreSQL](#postgresql)
34-
- [Sequelize](#sequelize)
35-
- [Docker](#docker)
36-
- [docker-compose](#docker-compose)
37-
- [Using this product](#using-this-product)
38-
- [Testing](#testing)
39-
- [Sources and Links](#sources-and-links)
40-
- [Contributors ✨](#contributors-)
41-
42-
<!-- /TOC -->
43-
44-
45-
46-
# Setup
47-
This setup section will focus on setting up the local dev environment. For more detailed instructions for how to deploy this to a production environment please see the section above this one :point_up:
48-
49-
To work on this project you should have:
50-
- [Node.js](https://nodejs.org/en/)
51-
- [PostgreSQL](https://www.postgresql.org/) (can be in Docker)
52-
- [Docker](https://www.docker.com/) (optional)
53-
- [Terraform](https://www.terraform.io/) (optional, for AWS deploy)
54-
Once you have the prerequisite software installed you can proceed to setup this application.
55-
56-
A `Dockerfile` and `docker-compose` file have been included for convenience, however this may not be the best local development setup for this project. For more information on how to use Docker with this project, please see the [docker section](#docker).
57-
58-
## Node and Express setup
59-
This application is designed to work as an API driven by Express. To setup your environment first you must install all required dependencies by running the following command from the root of your project directory:
60-
```
61-
npm install
62-
```
63-
Once all dependencies are installed you will need to setup some environment variables to interact with your database and application.
64-
65-
## Environment variables
66-
You will need to set some local environment variables to run this application. This is true even if you're using Docker.
67-
```
68-
touch .env
69-
echo 'NODE_ENV=local
70-
PORT=<your port>
71-
DATABASE_SCHEMA=<your database schema>
72-
JWT_KEY=<your secret JWT seed phrase or key>
73-
DATABASE_URL=<your db connection string>
74-
' >> ./.env
75-
```
76-
The `DATABASE_URL` is not a very clear var name, and the string is broken down as `postgres://username:password@host:port/database_name`
77-
78-
An example of the `DATABASE_URL` would be `DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres`
79-
80-
The various variables are defined as follows:
81-
- `NODE_ENV` = The label for your environment.
82-
- `PORT` = The local port you wish to run on. Defaults to `3000`.
83-
- `DATABASE_URL` = The URL string for your db connection. For example: `postgres://user:[email protected]:5432/dbname`
84-
- `DATABASE_SCHEMA` = Your local database schema. Postgres default is `public`.
85-
- `JWT_KEY` = A secret value to generate JWT's locally.
86-
- `URL` = The API URL
87-
- `DATABASE_USERNAME` = _optional for local dev_ Your database username.
88-
- `DATABASE_PASSWORD` = _optional for local dev_ Your database password.
89-
- `DATABASE_HOST` = _optional for local dev_ Your database host.
90-
- `DATABASE_PORT` = _optional for local dev_ Your database port.
91-
- `SMTP_HOST` = _optional_ hostname for the SMTP server used to send notification emails
92-
- `SMTP_PORT` = _optional_ port number for the SMTP server used to send notification emails
93-
- `SMTP_USER` = _optional_ username for the SMTP server used to send notification emails
94-
- `SMTP_PASSWORD` = _optional_ password for the SMTP server used to send notification emails
95-
- `URL` = _optional_ the URL for your front-end application
96-
- `TEST_EMAIL` = _optional_ the email you wish to send tests to
97-
- `BYPASS_LOGIN` = _optional_ Allows you to hit the endpoints locally without having to login. If you wish to bypass the login process during local dev, set this to `true`.
98-
99-
_We do not recommend using the default options for PostgreSQL. The above values are provided as examples. It is more secure to create your own credentials._
100-
101-
**Warning**: If you are running Docker Toolbox instead of Docker Desktop (likely meaning you are running Windows 10 Home, not Professional) you will need to change your `.env` to reflect Docker running on a VM:
102-
- `DATABASE_HOST`: The IP address Docker is running on. You can find this by running `docker-machine ip` but it's usually `192.168.99.100` instead of `localhost`
103-
- `DATABASE_URL`: This will need to be adjusted as well, for example `DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres` would become `DATABASE_URL=postgres://postgres:[email protected]:5432/postgres`
104-
105-
### Example .env
106-
To make this easier included below is an example `.env` file using all default values. ***We highly recommend*** you use custom values, but this should clarify what is needed for this to run.
107-
108-
```
109-
NODE_ENV=development
110-
PORT=3000
111-
JWT_KEY=test123
112-
DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres
113-
DATABASE_SCHEMA=public
114-
BYPASS_LOGIN=true
115-
URL=http://localhost:8080
116-
117-
```
118-
119-
## PostgreSQL
120-
***You will need a PostgreSQL database running locally to run this application locally.*** You may setup PostgreSQL however you wish, however we recommend using Docker using the instructions found here: https://hub.docker.com/_/postgres
121-
122-
If you are using Docker you may spin up your database layer by running this command:
123-
```
124-
docker run -d -e POSTGRES_PASSWORD=<your chosen password> -p 5432:5432 postgres
125-
```
126-
127-
If you're running a database in another way then we trust you can sort it out on your own because you're awesome :sunglasses:
128-
129-
### Sequelize
130-
To properly start the application the database needs to be built by Sequlize ahead of time. To do that run the following commands
131-
1. You must create your database tables without running the application by running `npm run db-create` first.
132-
2. _optional_ You can now seed your database if you wish by running `npm run db-seed`.
133-
134-
Example `/migrations` and `/seeders` scripts have been supplied. You can rollback your all seeded data at any time by running `npm run db-unseed` and delete all created tables with `npm run db-delete`.
135-
136-
## Docker
137-
You can build and run the application in Docker locally by running the following commands:
138-
```
139-
docker build -t bmoreres .
140-
docker run -d -p 3000:3000 --env-file=.env bmoreres
141-
```
142-
Note that `DATABASE_URL` host location will be different depending on what OS you're using. On Mac it is `docker.for.mac.host.internal` and on Windows it is `docker.for.win.host.internal` if using `docker-compose` it will be `db`. Please see [Example .env](#example-env) for more information.
143-
144-
Alternatively you can manually set the environment variables and not use a `.env` file by setting the following vars:
145-
```
146-
-e NODE_ENV=development
147-
-e PORT=3000
148-
-e JWT_KEY=<your JWT phrase>
149-
-e DATABASE_URL=<your connection string>
150-
-e DATABASE_DATABASE_SCHEMA=<your database schema>
151-
```
152-
153-
### docker-compose
154-
To use the `docker-compose.yml` file included you will first need to set [environment variables](#environment-variables). You **MUST** set your `DATABASE_HOST` to `db` to use the `docker-compose` solution. It is not recommended to use `docker-compose` for any reason other than to test a solution for a separate front-end component.
155-
156-
# Using this product
157-
You may use this product to create and manage users for your front-end.
158-
159-
To run the application--after the above steps are completed--run `npm start`.
160-
161-
## Testing
162-
To test your code you may write test cases to `./index.spec.js` and then run the tests with `npm test`.
163-
164-
To check your linting you may run `npm run lint` and to format and automatically fix your formatting run `npm run format`.
165-
16618
# Sources and Links
16719
We are also building a front-end application called [Healthcare Rollcall](https://github.com/CodeForBaltimore/Healthcare-Rollcall) to interact with this backend API. To view that project, or to contribute to it, please visit the repo here: https://github.com/CodeForBaltimore/Healthcare-Rollcall
16820

docs/SlowStart.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ If you want to deploy to AWS, we have included a `terraform` option. For more in
2424

2525
<TODO: Consider migrating terraform docs to be here or do some sort of INCLUDE to reuse the content>
2626

27+
## SMTP
28+
29+
To send emails with the system you will need to setup your SMTP sever and set the relevant `SMTP_*` variables. For testing we recommend using [Ethereal](https://ethereal.email/)
30+
2731
## Running in Docker
2832

2933
You can build and run the application in Docker locally by running the following commands:

src/email/index.js

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,17 @@ const sendForgotPassword = async (userEmail, resetPasswordToken) => {
5757

5858
const sendContactCheckInEmail = async (info) => {
5959
try {
60-
if (process.env.NODE_ENV === 'production' || process.env.TEST_EMAIL !== undefined && process.env.TEST_EMAIL === info.email) {
61-
const entityLink = `${process.env.FRONT_END_URL}/checkin/${info.entityId}?token=${info.token}`
62-
const emailTitle = `${info.entityName} Check In`
63-
const emailContents = `Hello ${info.name}! It is time to update the status of ${info.entityName}. Please click the link below to check in.`
64-
await sendMail(
65-
info.email,
66-
emailTitle,
67-
nunjucks.render("contact_check_in_html.njk", { emailTitle, emailContents, entityLink }),
68-
nunjucks.render("contact_check_in_text.njk", { emailTitle, emailContents, entityLink })
69-
)
70-
71-
return true
72-
}
60+
const entityLink = `${process.env.URL}/checkin/${info.entityId}?token=${info.token}`
61+
const emailTitle = `${info.entityName} Check In`
62+
const emailContents = `Hello ${info.name}! It is time to update the status of ${info.entityName}. Please click the link below to check in.`
63+
await sendMail(
64+
info.email,
65+
emailTitle,
66+
nunjucks.render("contact_check_in_html.njk", { emailTitle, emailContents, entityLink }),
67+
nunjucks.render("contact_check_in_text.njk", { emailTitle, emailContents, entityLink })
68+
)
69+
70+
return true
7371
} catch (e) {
7472
console.error(e)
7573
}

src/routes/contact.js

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -298,25 +298,36 @@ router.post('/link/:contact_id', async (req, res) => {
298298
id: req.params.contact_id
299299
}
300300
})
301+
302+
let i=0
301303
for (const entity of req.body.entities) {
302304
const entityToLink = await models.Entity.findOne({
303305
where: {
304306
id: entity.id
305307
}
306308
})
307309

308-
const ec = {
309-
entityId: entityToLink.id,
310-
contactId: contact.id,
311-
}
312-
313-
if (entity.title) {
314-
ec.relationshipTitle = contact.title
310+
if (contact !== null && entityToLink !== null) {
311+
const ec = {
312+
entityId: entityToLink.id,
313+
contactId: contact.id,
314+
}
315+
316+
if (entity.title) {
317+
ec.relationshipTitle = contact.title
318+
}
319+
320+
await models.EntityContact.createIfNew(ec)
321+
i++
315322
}
323+
}
316324

317-
await models.EntityContact.createIfNew(ec)
325+
if (i > 0) {
326+
response.setMessage(`Linking successful/already exists for contact with ID ${contact.id}`)
327+
} else {
328+
response.setCode(400)
329+
response.setMessage('Bad entities or contact id')
318330
}
319-
response.setMessage(`Linking successful/already exists for contact with ID ${contact.id}`)
320331
} else {
321332
response.setCode(400)
322333
}
@@ -338,24 +349,34 @@ router.post('/unlink/:contact_id', async (req, res) => {
338349
id: req.params.contact_id
339350
}
340351
})
352+
353+
let i=0
341354
for (const entity of req.body.entities) {
342355
const entityToUnLink = await models.Entity.findOne({
343356
where: {
344357
id: entity.id
345358
}
346359
})
347360

348-
// ideally only one of these should exist
349-
const ec = await models.EntityContact.findOne({
350-
where: {
351-
entityId: entityToUnLink.id,
352-
contactId: contact.id
353-
}
354-
})
355-
356-
await ec.destroy()
361+
if (contact !== null && entityToUnLink !== null) {
362+
// ideally only one of these should exist
363+
const ec = await models.EntityContact.findOne({
364+
where: {
365+
entityId: entityToUnLink.id,
366+
contactId: contact.id
367+
}
368+
})
369+
370+
await ec.destroy()
371+
i++
372+
}
373+
}
374+
if (i > 0) {
375+
response.setMessage(`Unlinking successful for contact with ID ${contact.id}`)
376+
} else {
377+
response.setCode(400)
378+
response.setMessage('Bad link sent')
357379
}
358-
response.setMessage(`Unlinking successful for contact with ID ${contact.id}`)
359380
} else {
360381
response.setCode(400)
361382
}

src/routes/user.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ router.post('/', utils.authMiddleware, async (req, res) => {
152152
await e.addRoleForUser(email.toLowerCase(), role)
153153
}
154154
}
155-
156155

157156
response.setMessage(user.email + ' created')
158157
} else {

0 commit comments

Comments
 (0)