remove unused files and dependencies

This commit is contained in:
Sam 2020-09-16 15:04:22 +02:00
parent b411d4d547
commit 640385cdb7
17 changed files with 54 additions and 2560 deletions

View File

@ -1,58 +0,0 @@
version: '3.3'
services:
fittrackee-db:
container_name: fittrackee-db
build: ./fittrackee_api/db
ports:
- 5435:5432
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
fittrackee-api:
container_name: fittrackee-api
build: ./fittrackee_api
ports:
- 5001:5000
environment:
- DATABASE_URL=postgres://postgres:postgres@fittrackee-db:5432/fittrackee
- DATABASE_TEST_URL=postgres://postgres:postgres@fittrackee-db:5432/fittrackee_test
- UI_URL=http://127.0.0.1:3000
- EMAIL_URL=smtp://none:none@0.0.0.0:1025
- SENDER_EMAIL=fittrackee@example.com
- FLASK_APP=server.py
- FLASK_DEBUG=1
- APP_SETTINGS=fittrackee_api.config.DevelopmentConfig
depends_on:
- fittrackee-db
links:
- fittrackee-db
fittrackee-client:
container_name: fittrackee-client
build:
context: ./
dockerfile: ./fittrackee_client/Dockerfile
args:
- NODE_ENV=development
- REACT_APP_API_URL=${REACT_APP_API_URL}
ports:
- 3007:3000
depends_on:
- fittrackee-api
links:
- fittrackee-api
nginx:
container_name: nginx
build: ./nginx
restart: always
ports:
- 80:80
depends_on:
- fittrackee-api
- fittrackee-client
links:
- fittrackee-api

View File

@ -1,31 +0,0 @@
FROM python:3.7
MAINTAINER SamR1@users.noreply.github.com
# set working directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# add requirements
COPY ./pyproject.toml /usr/src/app/pyproject.toml
COPY ./poetry.lock /usr/src/app/poetry.lock
# add environment variables
ARG UI_URL
ARG EMAIL_URL
ARG SENDER_EMAIL
ENV UI_URL $UI_URL
ENV EMAIL_URL $EMAIL_URL
ENV SENDER_EMAIL $SENDER_EMAIL
# install requirements
RUN pip install --upgrade pip
RUN pip install poetry
RUN poetry config virtualenvs.create false
RUN poetry install --no-interaction --quiet
# add app --no-interaction
COPY . /usr/src/app
# run server
CMD flask run --with-threads -h 0.0.0.0

View File

@ -1,5 +0,0 @@
FROM postgres:11.2
MAINTAINER SamR1@users.noreply.github.com
COPY create.sql /docker-entrypoint-initdb.d

View File

@ -1,31 +0,0 @@
FROM node:13.13.0
MAINTAINER SamR1@users.noreply.github.com
# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# add environment variables
ARG REACT_APP_API_URL
ARG NODE_ENV
ARG REACT_APP_ALLOW_REGISTRATION
ARG CI
ENV NODE_ENV $NODE_ENV
ENV REACT_APP_API_URL $REACT_APP_API_URL
ENV REACT_APP_ALLOW_REGISTRATION $REACT_APP_ALLOW_REGISTRATION
ENV CI $CI
# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN yarn install --silent
RUN yarn global add react-scripts
# add app
COPY . /usr/src/app/
# start app
CMD yarn start

View File

@ -1,43 +0,0 @@
import { Selector } from 'testcafe'
import { TEST_URL } from './utils'
const randomstring = require('randomstring')
const username = randomstring.generate(8)
const email = `${username}@test.com`
const password = 'lentghOk'
// eslint-disable-next-line no-undef
fixture('/activities').page(`${TEST_URL}/activities`)
test('standard user should be able to add a workout (w/o gpx)', async t => {
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
await t
.navigateTo(`${TEST_URL}/activities/add`)
.expect(Selector('H1').withText('Dashboard').exists).notOk()
.expect(Selector('H2').withText('Add a workout').exists).ok()
.click(Selector('input[name="withoutGpx"]'))
.click(Selector('select').filter('[name="sport_id"]'))
.click(Selector('option').filter('[value="1"]'))
.typeText('input[name="activity_date"]', '2018-12-20')
.typeText('input[name="activity_time"]', '14:05')
.typeText('input[name="duration"]', '01:00:00')
.typeText('input[name="distance"]', '10')
.click(Selector('input[type="submit"]'))
// pb w/ chromium to check
// await t
// .expect(Selector('H1').withText('Dashboard').exists).notOk()
// .expect(Selector('H1').withText('Activity').exists).ok()
})

View File

@ -1,25 +0,0 @@
import { Selector } from 'testcafe'
import { TEST_URL } from './utils'
// database must be initialiazed
const adminEmail = 'admin@example.com'
const adminPassword = 'mpwoadmin'
// eslint-disable-next-line no-undef
fixture('/admin/sports').page(`${TEST_URL}/admin/sports`)
test('admin should be able to access sports administration page', async t => {
// admin login
await t
.navigateTo(`${TEST_URL}/login`)
.typeText('input[name="email"]', adminEmail)
.typeText('input[name="password"]', adminPassword)
.click(Selector('input[type="submit"]'))
await t
.navigateTo(`${TEST_URL}/admin/sports`)
.expect(Selector('H1').withText('Administration - Sports').exists).ok()
.expect(Selector('TD').withText('Hiking').exists).ok()
})

View File

@ -1,50 +0,0 @@
import { Selector } from 'testcafe'
import { TEST_URL } from './utils'
const randomstring = require('randomstring')
const username = randomstring.generate(8)
const email = `${username}@test.com`
const password = 'lentghOk'
// database must be initialiazed
const adminEmail = 'admin@example.com'
const adminPassword = 'mpwoadmin'
// eslint-disable-next-line no-undef
fixture('/admin').page(`${TEST_URL}/admin`)
test('standard user should not be able to access admin page', async t => {
// register user
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
await t
.navigateTo(`${TEST_URL}/admin`)
.expect(Selector('H1').withText('Access denied').exists).ok()
.expect(Selector('H1').withText('Dashboard').exists).notOk()
})
test('admin should be able to access admin page', async t => {
// admin login
await t
.navigateTo(`${TEST_URL}/login`)
.typeText('input[name="email"]', adminEmail)
.typeText('input[name="password"]', adminPassword)
.click(Selector('input[type="submit"]'))
await t
.navigateTo(`${TEST_URL}/admin`)
.expect(Selector('H1').withText('Access denied').exists).notOk()
.expect(Selector('H1').withText('Administration').exists).ok()
.expect(Selector('.admin-items').withText('Sports').exists).ok()
})

View File

@ -1,15 +0,0 @@
import { Selector } from 'testcafe'
import { TEST_URL } from './utils'
// eslint-disable-next-line no-undef
fixture('/').page(`${TEST_URL}/`)
test('users should be able to view the \'/\' page', async t => {
await t
.navigateTo(TEST_URL)
.expect(Selector('A').withText('Dashboard').exists).ok()
})

View File

@ -1,97 +0,0 @@
import { Selector } from 'testcafe'
import { TEST_URL } from './utils'
const randomstring = require('randomstring')
const username = randomstring.generate(8)
const email = `${username}@test.com`
const password = 'lentghOk'
// eslint-disable-next-line no-undef
fixture('/login').page(`${TEST_URL}/login`)
test('should display the registration form', async t => {
await t
.navigateTo(`${TEST_URL}/login`)
.expect(Selector('H1').withText('Login').exists).ok()
.expect(Selector('form').exists).ok()
.expect(Selector('input[name="username"]').exists).notOk()
.expect(Selector('input[name="email"]').exists).ok()
.expect(Selector('input[name="password"]').exists).ok()
.expect(Selector('input[name="password_conf"]').exists).notOk()
})
test('should throw an error if the user is not registered', async t => {
// register user with duplicate user name
await t
.navigateTo(`${TEST_URL}/login`)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Login').exists).ok()
.expect(Selector('code').withText(
'Invalid credentials.').exists).ok()
})
test('should allow a user to login', async t => {
// register user
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
await t
.navigateTo(`${TEST_URL}/logout`)
.navigateTo(`${TEST_URL}/login`)
.expect(Selector('H1').withText('Login').exists).ok()
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.click(Selector('input[type="submit"]'))
// assert user is redirected to '/'
await t
.expect(Selector('H1').withText('Login').exists).notOk()
})
test('should throw an error if the email is invalid', async t => {
// register user with duplicate user name
await t
.navigateTo(`${TEST_URL}/login`)
.typeText('input[name="email"]', `${email}2`)
.typeText('input[name="password"]', password)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Login').exists).ok()
.expect(Selector('code').withText(
'Invalid credentials.').exists).ok()
})
test('should throw an error if the password is invalid', async t => {
// register user with duplicate user name
await t
.navigateTo(`${TEST_URL}/login`)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', `${password}2`)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Login').exists).ok()
.expect(Selector('code').withText(
'Invalid credentials.').exists).ok()
})

View File

@ -1,40 +0,0 @@
import { Selector } from 'testcafe'
import { TEST_URL } from './utils'
const randomstring = require('randomstring')
const username = randomstring.generate(8)
const email = `${username}@test.com`
const password = 'lentghOk'
// eslint-disable-next-line no-undef
fixture('/profile').page(`${TEST_URL}/profile`)
test('should be able to access his profile page', async t => {
// register user
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
await t
.navigateTo(`${TEST_URL}/logout`)
.navigateTo(`${TEST_URL}/login`)
.expect(Selector('H1').withText('Login').exists).ok()
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.click(Selector('input[type="submit"]'))
await t
.navigateTo(`${TEST_URL}/profile`)
.expect(Selector('H1').withText('Login').exists).notOk()
.expect(Selector('H1').withText('Dashboard').exists).notOk()
.expect(Selector('H1').withText('Profile').exists).ok()
.expect(Selector('.userName').withText(username).exists).ok()
})

View File

@ -1,177 +0,0 @@
import { Selector } from 'testcafe'
import { TEST_URL } from './utils'
const randomstring = require('randomstring')
let username = randomstring.generate(8)
const email = `${username}@test.com`
const password = 'lentghOk'
// eslint-disable-next-line no-undef
fixture('/register').page(`${TEST_URL}/register`)
test('should display the registration form', async t => {
await t
.navigateTo(`${TEST_URL}/register`)
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('form').exists).ok()
.expect(Selector('input[name="username"]').exists).ok()
.expect(Selector('input[name="email"]').exists).ok()
.expect(Selector('input[name="password"]').exists).ok()
.expect(Selector('input[name="password_conf"]').exists).ok()
})
test('should allow a user to register', async t => {
// register user
await t
.navigateTo(`${TEST_URL}/register`)
.expect(Selector('H1').withText('Register').exists).ok()
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
// assert user is redirected to '/'
await t
.expect(Selector('H1').withText('Register').exists).notOk()
})
test('should throw an error if the username is taken', async t => {
// register user with duplicate user name
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', `${email}2`)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('code').withText(
'Sorry. That user already exists.').exists).ok()
})
username = randomstring.generate(8)
test('should throw an error if the email is taken', async t => {
// register user with duplicate email
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', `${username}2`)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('code').withText(
'Sorry. That user already exists.').exists).ok()
})
test('should throw an error if the username is too short', async t => {
const shortUsername = 'a'
// register user with duplicate email
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', `${shortUsername}`)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('code').withText(
'3 to 12 characters required for username.').exists).ok()
})
test('should throw an error if the user is too long', async t => {
const longUsername = randomstring.generate(20)
// register user with duplicate email
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', `${longUsername}`)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('code').withText(
'3 to 12 characters required for username.').exists).ok()
})
test('should throw an error if the email is invalid', async t => {
const invalidEmail = `${username}@test`
// register user with duplicate email
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', invalidEmail)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', password)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('code').withText(
'Valid email must be provided.').exists).ok()
})
test('should throw an error if passwords don\'t match', async t => {
// register user with duplicate email
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', password)
.typeText('input[name="password_conf"]', `${password}2`)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('code').withText(
'Password and password confirmation don\'t match.').exists).ok()
})
test('should throw an error if the password is too short', async t => {
const invalidPassword = '1234567'
// register user with duplicate email
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', invalidPassword)
.typeText('input[name="password_conf"]', invalidPassword)
.click(Selector('input[type="submit"]'))
// assert user registration failed
await t
.expect(Selector('H1').withText('Register').exists).ok()
.expect(Selector('code').withText(
'8 characters required for password.').exists).ok()
})

View File

@ -1 +0,0 @@
export const TEST_URL = process.env.TEST_URL

View File

@ -1,6 +0,0 @@
FROM nginx:1.13.0
MAINTAINER SamR1@users.noreply.github.com
RUN rm /etc/nginx/conf.d/default.conf
COPY /nginx.conf /etc/nginx/conf.d

View File

@ -1,23 +0,0 @@
server {
listen 80;
location / {
proxy_pass http://fittrackee-client:3000;
proxy_redirect default;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /api {
proxy_pass http://fittrackee-api:5000;
proxy_redirect default;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}

View File

@ -29,7 +29,6 @@
"scripts": {
"start": "cd fittrackee_client && react-scripts start",
"build": "NODE_ENV=production cd fittrackee_client && react-scripts build && rm -rf ../fittrackee_api/dist/* && cp -a build/. ../fittrackee_api/dist",
"test": "cd fittrackee_client && testcafe firefox e2e",
"eject": "cd fittrackee_client && react-scripts eject",
"lint": "eslint --cache --ext .jsx --ext .js fittrackee_client/src",
"lint-fix": "eslint --cache --ext .jsx --ext .js fittrackee_client/src --fix"
@ -47,8 +46,6 @@
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-testcafe": "^0.2.1",
"prettier": "^2.1.2",
"randomstring": "^1.1.5",
"testcafe": "^1.9.2"
"prettier": "^2.1.2"
}
}

28
test.sh
View File

@ -1,28 +0,0 @@
#!/bin/bash
fails=''
inspect() {
if [ $1 -ne 0 ]; then
fails="${fails} $2"
fi
}
docker-compose -f docker-compose-ci.yml run fittrackee-api py.test fittrackee_api -p no:warnings
inspect $? api
docker-compose -f docker-compose-ci.yml run fittrackee-api flask db upgrade
docker-compose -f docker-compose-ci.yml run fittrackee-api flask initdata
docker-compose -f docker-compose-ci.yml restart fittrackee-api
testcafe chrome fittrackee_client/e2e -e
inspect $? e2e
if [ -n "${fails}" ];
then
echo "Tests failed: ${fails}"
exit 1
else
echo "Tests passed!"
exit 0
fi

1979
yarn.lock

File diff suppressed because it is too large Load Diff