diff --git a/.gitignore b/.gitignore
index 91b4877..ffa6af6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,8 @@ backend/dist
.env.development.local
.env.test.local
.env.production.local
+.env
+env.json
dist
npm-debug.log*
@@ -30,4 +32,6 @@ frontend/server.key
frontend/server.cert
backend/server.key
-backend/server.cert
\ No newline at end of file
+backend/server.cert
+
+logs
diff --git a/Dockerfile b/Dockerfile
index 6378271..67c0f04 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,49 +1,17 @@
-# OVERVIEW: This is the Dockerfile for a multi-stage build of the CDS Authoring
-# Tool. A multi-stage approach was used to keep the overall image size low by
-# including only the layers needed at runtime in the final image. For more
-# info see: https://docs.docker.com/develop/develop-images/multistage-build/
-
-###############################################################################
-# STAGE 0: base
-# - Setup base image from which most others derive. This allows for a single
-# place to declare the versioned node image we use and any other commands
-# common to all (or most?) environments.
-###############################################################################
-
-FROM node:18-alpine as base
+FROM node:14-alpine
ENV NODE_ENV production
-# ADD https://gitlab.mitre.org/mitre-scripts/mitre-pki/raw/master/os_scripts/install_certs.sh /tmp/install_certs.sh
-# RUN chmod a+x /tmp/install_certs.sh && /tmp/install_certs.sh && rm /tmp/install_certs.sh
-
-# RUN apk update
-# RUN apk upgrade openssl
-# First copy just the package.json, package-lock.json, and local dependencies so that
-# if they have not changed, we can use cached node_modules instead of
-# redownloading them all.
-COPY ./ /usr/src/app/
-WORKDIR /usr/src/app/backend
-
-
+WORKDIR /home/node/app
+COPY --chown=node:node . .
+WORKDIR /home/node/app/backend
RUN npm install
-
-RUN ls -la
-
-
-
-WORKDIR /usr/src/app/frontend
+WORKDIR /home/node/app/frontend
RUN npm install
+WORKDIR /home/node/app
-
-RUN npm install -g pm2@4.4.1
-WORKDIR /usr/src/app
-RUN chown -R node:node .
-ENV PORT 5050
+RUN npm install pm2 -g
EXPOSE 5050
EXPOSE 5051
-USER node
-
-
CMD [ "pm2-docker", "pm2.config.js" ]
\ No newline at end of file
diff --git a/Dockerfile.dev b/Dockerfile.dev
index 93659e8..436f2df 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -1,41 +1,16 @@
-# OVERVIEW: This is the Dockerfile for a multi-stage build of the CDS Authoring
-# Tool. A multi-stage approach was used to keep the overall image size low by
-# including only the layers needed at runtime in the final image. For more
-# info see: https://docs.docker.com/develop/develop-images/multistage-build/
-
-###############################################################################
-# STAGE 0: base
-# - Setup base image from which most others derive. This allows for a single
-# place to declare the versioned node image we use and any other commands
-# common to all (or most?) environments.
-###############################################################################
-
-FROM node:14-alpine as base
-
-
-# First copy just the package.json, package-lock.json, and local dependencies so that
-# if they have not changed, we can use cached node_modules instead of
-# redownloading them all.
-COPY ./ /usr/src/app/
-WORKDIR /usr/src/app/backend
-
+FROM node:14-alpine
+WORKDIR /home/node/app
+COPY --chown=node:node . .
+WORKDIR /home/node/app/backend
RUN npm install
-RUN npm run build
-
-WORKDIR /usr/src/app/frontend
+WORKDIR /home/node/app/frontend
RUN npm install
+WORKDIR /home/node/app
-
-
-RUN npm install -g pm2@4.4.1
-WORKDIR /usr/src/app
-RUN chown -R node:node .
-ENV PORT 5050
+RUN npm install pm2 -g
EXPOSE 5050
EXPOSE 5051
-USER node
-
CMD ./dockerRunnerDev.sh
\ No newline at end of file
diff --git a/backend/package-lock.json b/backend/package-lock.json
index cdc3031..b997dcc 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -42,7 +42,7 @@
"eslint-plugin-prettier": "^4.2.1",
"json-diff": "^0.9.0",
"mocha": "^10.2.0",
- "mongodb": "5.5.0",
+ "mongodb": "5.8.0",
"mongodb-memory-server": "^8.12.1",
"nock": "^13.2.9",
"nodemon": "^2.0.20",
@@ -815,6 +815,16 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
+ "node_modules/@mongodb-js/saslprep": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz",
+ "integrity": "sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -4342,12 +4352,12 @@
}
},
"node_modules/mongodb": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.5.0.tgz",
- "integrity": "sha512-XgrkUgAAdfnZKQfk5AsYL8j7O99WHd4YXPxYxnh8dZxD+ekYWFRA3JktUsBnfg+455Smf75/+asoU/YLwNGoQQ==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.8.0.tgz",
+ "integrity": "sha512-xx4CXmxcj3bNe7iGBlhntVrUqrNARYhUZteXaz4epEESv4oXD/FONAovcyoCaEffdYlw25Yz284OxMfpnPLlgQ==",
"dev": true,
"dependencies": {
- "bson": "^5.3.0",
+ "bson": "^5.4.0",
"mongodb-connection-string-url": "^2.6.0",
"socks": "^2.7.1"
},
@@ -4355,10 +4365,12 @@
"node": ">=14.20.1"
},
"optionalDependencies": {
- "saslprep": "^1.0.3"
+ "@mongodb-js/saslprep": "^1.1.0"
},
"peerDependencies": {
- "@aws-sdk/credential-providers": "^3.201.0",
+ "@aws-sdk/credential-providers": "^3.188.0",
+ "@mongodb-js/zstd": "^1.0.0",
+ "kerberos": "^1.0.0 || ^2.0.0",
"mongodb-client-encryption": ">=2.3.0 <3",
"snappy": "^7.2.2"
},
@@ -4366,6 +4378,12 @@
"@aws-sdk/credential-providers": {
"optional": true
},
+ "@mongodb-js/zstd": {
+ "optional": true
+ },
+ "kerberos": {
+ "optional": true
+ },
"mongodb-client-encryption": {
"optional": true
},
diff --git a/backend/package.json b/backend/package.json
index 05c4cb8..fe8e3ab 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -37,7 +37,7 @@
"eslint-plugin-prettier": "^4.2.1",
"json-diff": "^0.9.0",
"mocha": "^10.2.0",
- "mongodb": "5.5.0",
+ "mongodb": "5.8.0",
"mongodb-memory-server": "^8.12.1",
"nock": "^13.2.9",
"nodemon": "^2.0.20",
@@ -48,7 +48,7 @@
"typescript": "^4.9.3"
},
"scripts": {
- "start": "tsc && nodemon ./dist/server.js",
+ "start": "ts-node-dev src/server.ts",
"test": "mocha",
"build": "tsc",
"lint": "tsc && eslint \"**/*.{js,ts}\"",
diff --git a/dockerRunnerDev.sh b/dockerRunnerDev.sh
index 59cd204..02a0cfd 100755
--- a/dockerRunnerDev.sh
+++ b/dockerRunnerDev.sh
@@ -1,26 +1,27 @@
#!/bin/sh
# Handle closing application on signal interrupt (ctrl + c)
-trap 'kill $CONTINUOUS_INSTALL_PID $SERVER_PID; gradle --stop; exit' INT
+trap 'kill $CONTINUOUS_INSTALL_PID $SERVER_PID $BACKEND_SERVER_PID; exit' INT
mkdir logs
+
# Reset log file content for new application boot
-echo "*** Logs for continuous installer ***" > ./frontend/logs/installer.log
-echo "*** Logs for 'npm run start' ***" > ./frontent/logs/runner.log
+echo "*** Logs for continuous frontend installer ***" > ./logs/frontend_installer.log
+echo "*** Logs for frontend 'npm run start' ***" > ./logs/frontend_runner.log
-echo "*** Logs for continuous installer ***" > ./backend/logs/installer.log
-echo "*** Logs for 'npm run start' ***" > ./backend/logs/runner.log
+echo "*** Logs for continuous backend installer ***" > ./logs/backend_installer.log
+echo "*** Logs for backend 'npm run start' ***" > ./logs/backend_runner.log
# Print that the application is starting in watch mode
echo "starting application in watch mode..."
# Start the continious build listener process
-echo "starting continuous installer..."
+echo "starting continuous installers..."
cd frontend
-npm install | tee ./logs/installer.log
+npm install | tee ./logs/frontend_installer.log
cd ../backend
-npm install | tee ./logs/installer.log
+npm install | tee ./logs/backend_installer.log
cd ..
( package_modify_time=$(stat -c %Y frontend/package.json)
@@ -36,13 +37,16 @@ do
if [[ "$package_modify_time" != "$new_package_modify_time" ]] || [[ "$package_lock_modify_time" != "$new_package_lock_modify_time" ]] || [[ "$backend_lock_modify_time" != "$new_backend_lock_modify_time" ]]|| [[ "$backend_modify_time" != "$new_backend_modify_time" ]]
then
- echo "running npm install..."
+ echo "running frontent npm install..."
cd frontend
- npm install | tee ./logs/installer.log
- cd ../backend
- npm install | tee ./logs/installer.log
+ npm install | tee ./logs/frontend_installer.log
+ cd ..
+ elif [[ "$backend_lock_modify_time" != "$new_backend_lock_modify_time" ]]|| [[ "$backend_modify_time" != "$new_backend_modify_time" ]]
+ then
+ echo "running backend npm install..."
+ cd backend
+ npm install | tee ./logs/backend_installer.log
cd ..
- pm2-docker pm2.config.dev.js
fi
package_modify_time=$new_package_modify_time
@@ -53,10 +57,14 @@ do
done ) & CONTINUOUS_INSTALL_PID=$!
# Start server process once initial build finishes
-( pm2-docker pm2.config.js ) & SERVER_PID=$!
+cd frontend
+( npm run start | tee ./logs/frontend_runner.log ) & SERVER_PID=$!
+
+cd ../backend
+( npm run start | tee ./logs/backend_runner.log ) & BACKEND_SERVER_PID=$!
# Handle application background process exiting
-wait $CONTINUOUS_INSTALL_PID $SERVER_PID
+wait $CONTINUOUS_INSTALL_PID $SERVER_PID $BACKEND_SERVER_PID
EXIT_CODE=$?
echo "application exited with exit code $EXIT_CODE..."
diff --git a/frontend/.env b/frontend/.env
new file mode 100644
index 0000000..7e845eb
--- /dev/null
+++ b/frontend/.env
@@ -0,0 +1,2 @@
+PORT=5050
+REACT_APP_PIMS_BACKEND_PORT=5051
\ No newline at end of file
diff --git a/frontend/env.json b/frontend/env.json
deleted file mode 100644
index 172333d..0000000
--- a/frontend/env.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-"BACKEND_PORT" : {
- "type" :"number",
- "default" : 5051
-},
-"ALLOWED_ORIGIN" : {
- "type" : "object",
- "default" : ["http://localhost:3000", "https://localhost:3000/", "http://localhost:3005", "https://localhost:3005/", "http://localhost:5050", "https://localhost:5050/", "http://localhost:4040", "https://localhost:4040/"]
-},
-"MONGO_USERNAME": {
- "type" : "string",
- "default" : "rems-admin-pims-root"
-},
-
-"MONGO_PASSWORD" :{
- "type" : "string",
- "default" : "rems-admin-pims-password"
-},
-
-"MONGO_URL" : {
- "type" : "string",
- "default" : "mongodb://localhost:27017/pims"
-},
-
-"AUTH_SOURCE" :{
- "type" : "string",
- "default" : "admin"
-},
-
-"REMS_ADMIN_BASE" : {
- "type" : "string",
- "default" : "http://localhost:8090"
-},
-
-"PORT" : {
- "type" :"number",
- "default" : 5050
-},
-"SSL_KEY_FILE": {
- "type": "string",
- "default": "server.key"
-},
-"SSL_CRT_FILE": {
- "type": "string",
- "default": "server.cert"
-},
-"USE_HTTPS": {
- "type": "boolean",
- "default": false
-}
-}
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 626f03b..51ff208 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -56,9 +56,9 @@
}
},
"node_modules/@adobe/css-tools": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.1.0.tgz",
- "integrity": "sha512-mMVJ/j/GbZ/De4ZHWbQAQO1J6iVnjtZLc9WEdkUQb8S/Bu2cAF2bETXUgMAdvMG3/ngtKmcNBe+Zms9bg6jnQQ=="
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz",
+ "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg=="
},
"node_modules/@ampproject/remapping": {
"version": "2.2.0",
diff --git a/frontend/src/views/DoctorOrders/NewOrders/NewOrders.test.tsx b/frontend/src/views/DoctorOrders/NewOrders/NewOrders.test.tsx
index 3004e37..51dd590 100644
--- a/frontend/src/views/DoctorOrders/NewOrders/NewOrders.test.tsx
+++ b/frontend/src/views/DoctorOrders/NewOrders/NewOrders.test.tsx
@@ -1,9 +1,18 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
import NewOrders from './NewOrders';
+import axios from 'axios';
-test('renders NewOrders', () => {
- render();
- const linkElement = screen.getByText(/NewOrders/i);
- expect(linkElement).toBeInTheDocument();
+jest.mock('axios');
+describe('', () => {
+
+ it('renders the order card with no doctor orders', async () => {
+ axios.get = jest.fn().mockImplementationOnce(() => Promise.resolve({ data: [] }));
+ render();
+
+ await waitFor(() => {
+ const linkElement = screen.getByText(/NewOrders/i);
+ expect(linkElement).toBeInTheDocument();
+ });
+ });
});
\ No newline at end of file
diff --git a/frontend/src/views/DoctorOrders/OrderCard/OrderCard.test.tsx b/frontend/src/views/DoctorOrders/OrderCard/OrderCard.test.tsx
index 90bd1eb..f7a1888 100644
--- a/frontend/src/views/DoctorOrders/OrderCard/OrderCard.test.tsx
+++ b/frontend/src/views/DoctorOrders/OrderCard/OrderCard.test.tsx
@@ -1,9 +1,62 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
import OrderCard from './OrderCard';
+import axios from 'axios';
-test.skip('renders Status', () => {
- render();
- const linkElement = screen.getByText("Total");
- expect(linkElement).toBeInTheDocument();
+const doctorOrders = [{caseNumber: '1694010494795',
+ dispenseStatus: 'Pending',
+ doctorContact: '716-873-1557',
+ doctorEmail: 'jane.betty@myhospital.com',
+ doctorID: '1122334455',
+ doctorName: 'Dr. Jane Doe',
+ drugNames:'Turalio 200 MG Oral Capsule',
+ drugNdcCode: '65597-402-20',
+ drugPrice: 200,
+ metRequirements: [],
+ patientCity: 'Winterfell',
+ patientCountry: 'US',
+ patientDOB: '1996-06-01',
+ patientFirstName: 'Jon',
+ patientLastName: 'Snow',
+ patientName: 'Jon Snow',
+ patientPostalCode: '00008',
+ patientStateProvince: 'Westeros',
+ pickupDate: 'Tue Dec 13 2022',
+ quanitities: '90',
+ rxDate: '2020-07-11',
+ simpleDrugName: 'Turalio',
+ total: 1800}];
+
+jest.mock('axios');
+
+describe('', () => {
+ it('renders the order card with no doctor orders', async () => {
+ axios.get = jest.fn().mockImplementationOnce(() => Promise.resolve({ data: [] }));
+ render();
+
+ await waitFor(() => {
+ expect(screen.getByRole('heading', { name: /no orders yet\./i })).toBeInTheDocument();
+ });
+ });
+
+ it('renders the order card and any doctor orders', async () => {
+ axios.get = jest.fn().mockImplementationOnce(() => Promise.resolve({ data: doctorOrders }));
+ render();
+
+ await waitFor(() => {
+ expect(screen.getByText(/Jon Snow/i)).toBeInTheDocument();
+ expect(screen.getByText(/1996/i)).toBeInTheDocument();
+ expect(screen.getByText(/Turalio/i)).toBeInTheDocument();
+ expect(screen.getByText(/Pending/i)).toBeInTheDocument();
+ // expect(screen.getByTestId('quantities')).toBeInTheDocument();
+ // expect(screen.getByTestId('drugPrice')).toBeInTheDocument();
+ // expect(screen.getByTestId('total')).toBeInTheDocument();
+ // expect(screen.getByTestId('doctorName')).toBeInTheDocument();
+ // expect(screen.getByTestId('doctorID')).toBeInTheDocument();
+ // expect(screen.getByTestId('doctorContact')).toBeInTheDocument();
+ // expect(screen.getByTestId('doctorEmail')).toBeInTheDocument();
+ // expect(screen.getByTestId('pickupDate')).toBeInTheDocument();
+ expect(screen.getByRole('button', { name: /remove all/i })).toBeInTheDocument();
+ });
+ });
});
\ No newline at end of file
diff --git a/frontend/src/views/DoctorOrders/OrderCard/OrderCard.tsx b/frontend/src/views/DoctorOrders/OrderCard/OrderCard.tsx
index de771e9..25d1b7d 100644
--- a/frontend/src/views/DoctorOrders/OrderCard/OrderCard.tsx
+++ b/frontend/src/views/DoctorOrders/OrderCard/OrderCard.tsx
@@ -45,6 +45,7 @@ interface DoctorOrder {
const OrderCard = (props: any) => {
const [doctorOrder, setDoctorOrders] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
//remove all doctorOrders
const deleteAll = async () => {
@@ -59,17 +60,21 @@ const OrderCard = (props: any) => {
getAllDoctorOrders();
}, []);
- const getAllDoctorOrders = () => {
- axios
+ const getAllDoctorOrders = async () => {
+ await axios
.get(url)
.then(function (response) {
const allDoctorOrders = response.data;
+ setIsLoading(false);
setDoctorOrders(allDoctorOrders);
})
- .catch(error => console.error(`Error: ${error}`));
+ .catch(error => {
+ setIsLoading(false);
+ console.error(`Error: ${error}`);
+ });
};
- if (doctorOrder.length < 1) {
+ if (doctorOrder.length < 1 && !isLoading) {
return (
No orders yet.
diff --git a/frontend/src/views/DoctorOrders/PickedUpOrders/PickedUpOrders.test.tsx b/frontend/src/views/DoctorOrders/PickedUpOrders/PickedUpOrders.test.tsx
index f7dbf20..4b44995 100644
--- a/frontend/src/views/DoctorOrders/PickedUpOrders/PickedUpOrders.test.tsx
+++ b/frontend/src/views/DoctorOrders/PickedUpOrders/PickedUpOrders.test.tsx
@@ -1,9 +1,18 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
import PickedUpOrders from './PickedUpOrders';
+import axios from 'axios';
-test('renders PickedUpOrders', () => {
- render();
- const linkElement = screen.getByText(/PickedUpOrders/i);
- expect(linkElement).toBeInTheDocument();
+jest.mock('axios');
+describe('', () => {
+
+ it('renders the order card with no doctor orders', async () => {
+ axios.get = jest.fn().mockImplementationOnce(() => Promise.resolve({ data: [] }));
+ render();
+
+ await waitFor(() => {
+ const linkElement = screen.getByText(/PickedUpOrders/i);
+ expect(linkElement).toBeInTheDocument();
+ });
+ });
});
\ No newline at end of file
diff --git a/frontend/src/views/DoctorOrders/VerifiedOrders/VerifiedOrders.test.tsx b/frontend/src/views/DoctorOrders/VerifiedOrders/VerifiedOrders.test.tsx
index 5cd0e61..2a4b8ae 100644
--- a/frontend/src/views/DoctorOrders/VerifiedOrders/VerifiedOrders.test.tsx
+++ b/frontend/src/views/DoctorOrders/VerifiedOrders/VerifiedOrders.test.tsx
@@ -1,9 +1,19 @@
import React from 'react';
-import { render, screen } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
import VerifiedOrders from './VerifiedOrders';
+import axios from 'axios';
-test('renders VerifiedOrders', () => {
- render();
- const linkElement = screen.getByText(/VerifiedOrders/i);
- expect(linkElement).toBeInTheDocument();
-});
\ No newline at end of file
+
+jest.mock('axios');
+describe('', () => {
+
+ it('renders the order card with no doctor orders', async () => {
+ axios.get = jest.fn().mockImplementationOnce(() => Promise.resolve({ data: [] }));
+ render();
+
+ await waitFor(() => {
+ const linkElement = screen.getByText(/VerifiedOrders/i);
+ expect(linkElement).toBeInTheDocument();
+ });
+ });
+});