diff --git a/README.MD b/README.MD
deleted file mode 100644
index 60ab2bd..0000000
--- a/README.MD
+++ /dev/null
@@ -1,68 +0,0 @@
-# API FullStackOverflow Developer
-
-In API FullStackOverflow Developer people can freely post and answer questions.
-Each question can have only one answer or none (if it hasn't been answered yet)
-
-Try it out now at https://back-fullstackdeveloper.herokuapp.com/
-
-## About
-
-This is a API web app that lets you post and answer questions.
-
-- Post a new question
-- Register a new user to answer questions
-- Answer questions
-- See answered and unanswered questions
-
-## Technologies
-The following tools and frameworks were used in the construction of the project:
-
- 
- 
- 
- 
- 
- 
-
- ## How to run
-
-1. Clone this repository
-```bash
-git clone https://github.com/thipereira02/API_FullStackOverflow-Developer
-```
-
-2. Create a Database using the ``dump.sql`` file inside the ``dump`` folder by following these steps:
- - 2.1 Open your terminal. **Important: the terminal must be opened in the same path as the ``dump.sql`` file is located.**
- - 2.2 Access PostgreSQL using the command ``sudo su postgres`` and enter your password when prompted.
- - 2.3 Next, type ``psql postgres`` and hit enter.
- - 2.4 Create a database by typing ``CREATE DATABASE fullstack;`` and hitting enter.
- - 2.5 Type ``\q`` and hit enter.
- - 2.6 Finally, type ```psql fullstack < dump.sql``` and hit enter. Your database should be ready after this step.
-2. Set the environment variables by following these steps:
- - 3.1 Create a ``.env`` file in the folder root
- - 3.2 Copy the content of the ``.env.example`` into it
- - 3.3 Set the ``DATABASE_URL`` in this format: "postgres://user:password@host:port/fullstack"
- - 3.4 Set the ``PORT`` for 4000
-3. In your terminal, go back to the root folder and install the dependencies
-```bash
-npm i
-```
-5. Also in the root folder, run the back-end with
-```bash
-npm start
-```
-6. Your server should be running now.
-7. After that, you can optionally test the project following these steps:
- - 7.1 Open your terminal.
- - 7.2 Access PostgreSQL using the command ``sudo su postgres`` and enter your password when prompted.
- - 7.3 Next, type ``psql postgres`` and hit enter.
- - 7.4 Create a test database by typing ``CREATE DATABASE fullstack_test TEMPLATE fullstack;`` and hitting enter. Your database test should be ready after this step.
- - 7.5 Set the enviroment variable following the step 5 again, with the following changes:
- - 7.5.1 The file must be called ``.env.test``
- - 7.5.2 The ``DATABASE_URL`` must be in this format: "postgres://user:password@host:port/fullstack_test"
- - Important: the tests assume that some tables are pre-populated. Therefore, it is important to use the dump provided to create the test database.
-
-8. In your terminal, go to the root folder and run the tests with:
-```bash
-npm run test
-```
\ No newline at end of file
diff --git a/dump.sql b/dump.sql
deleted file mode 100644
index b93d455..0000000
--- a/dump.sql
+++ /dev/null
@@ -1,250 +0,0 @@
---
--- PostgreSQL database dump
---
-
--- Dumped from database version 12.9 (Ubuntu 12.9-0ubuntu0.20.04.1)
--- Dumped by pg_dump version 12.9 (Ubuntu 12.9-0ubuntu0.20.04.1)
-
-SET statement_timeout = 0;
-SET lock_timeout = 0;
-SET idle_in_transaction_session_timeout = 0;
-SET client_encoding = 'UTF8';
-SET standard_conforming_strings = on;
-SELECT pg_catalog.set_config('search_path', '', false);
-SET check_function_bodies = false;
-SET xmloption = content;
-SET client_min_messages = warning;
-SET row_security = off;
-
-SET default_tablespace = '';
-
-SET default_table_access_method = heap;
-
---
--- Name: classes; Type: TABLE; Schema: public; Owner: -
---
-
-CREATE TABLE public.classes (
- id integer NOT NULL,
- name character varying(2) NOT NULL
-);
-
-
---
--- Name: classes_id_seq; Type: SEQUENCE; Schema: public; Owner: -
---
-
-CREATE SEQUENCE public.classes_id_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
---
--- Name: classes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
---
-
-ALTER SEQUENCE public.classes_id_seq OWNED BY public.classes.id;
-
-
---
--- Name: questions; Type: TABLE; Schema: public; Owner: -
---
-
-CREATE TABLE public.questions (
- id integer NOT NULL,
- question text NOT NULL,
- "classId" integer NOT NULL,
- student character varying(255) NOT NULL,
- tags text NOT NULL,
- "submitAt" character varying(255) NOT NULL,
- answered boolean DEFAULT false NOT NULL,
- "answeredAt" character varying(255),
- "answeredBy" integer,
- answer text
-);
-
-
---
--- Name: questions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
---
-
-CREATE SEQUENCE public.questions_id_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
---
--- Name: questions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
---
-
-ALTER SEQUENCE public.questions_id_seq OWNED BY public.questions.id;
-
-
---
--- Name: students; Type: TABLE; Schema: public; Owner: -
---
-
-CREATE TABLE public.students (
- id integer NOT NULL,
- name character varying(255) NOT NULL,
- token text NOT NULL,
- "classId" integer NOT NULL
-);
-
-
---
--- Name: students_id_seq; Type: SEQUENCE; Schema: public; Owner: -
---
-
-CREATE SEQUENCE public.students_id_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
---
--- Name: students_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
---
-
-ALTER SEQUENCE public.students_id_seq OWNED BY public.students.id;
-
-
---
--- Name: classes id; Type: DEFAULT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.classes ALTER COLUMN id SET DEFAULT nextval('public.classes_id_seq'::regclass);
-
-
---
--- Name: questions id; Type: DEFAULT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.questions ALTER COLUMN id SET DEFAULT nextval('public.questions_id_seq'::regclass);
-
-
---
--- Name: students id; Type: DEFAULT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.students ALTER COLUMN id SET DEFAULT nextval('public.students_id_seq'::regclass);
-
-
---
--- Data for Name: classes; Type: TABLE DATA; Schema: public; Owner: -
---
-
-
-
---
--- Data for Name: questions; Type: TABLE DATA; Schema: public; Owner: -
---
-
-
-
---
--- Data for Name: students; Type: TABLE DATA; Schema: public; Owner: -
---
-
-
-
---
--- Name: classes_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
---
-
-SELECT pg_catalog.setval('public.classes_id_seq', 1, false);
-
-
---
--- Name: questions_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
---
-
-SELECT pg_catalog.setval('public.questions_id_seq', 1, false);
-
-
---
--- Name: students_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
---
-
-SELECT pg_catalog.setval('public.students_id_seq', 1, false);
-
-
---
--- Name: classes classes_name_key; Type: CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.classes
- ADD CONSTRAINT classes_name_key UNIQUE (name);
-
-
---
--- Name: classes classes_pk; Type: CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.classes
- ADD CONSTRAINT classes_pk PRIMARY KEY (id);
-
-
---
--- Name: questions questions_pk; Type: CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.questions
- ADD CONSTRAINT questions_pk PRIMARY KEY (id);
-
-
---
--- Name: students students_pk; Type: CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.students
- ADD CONSTRAINT students_pk PRIMARY KEY (id);
-
-
---
--- Name: students students_token_key; Type: CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.students
- ADD CONSTRAINT students_token_key UNIQUE (token);
-
-
---
--- Name: questions questions_fk0; Type: FK CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.questions
- ADD CONSTRAINT questions_fk0 FOREIGN KEY ("classId") REFERENCES public.classes(id);
-
-
---
--- Name: questions questions_fk1; Type: FK CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.questions
- ADD CONSTRAINT questions_fk1 FOREIGN KEY ("answeredBy") REFERENCES public.students(id);
-
-
---
--- Name: students students_fk0; Type: FK CONSTRAINT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY public.students
- ADD CONSTRAINT students_fk0 FOREIGN KEY ("classId") REFERENCES public.classes(id);
-
-
---
--- PostgreSQL database dump complete
---
-
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index 4a5b465..0000000
--- a/jest.config.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = {
- preset: 'ts-jest',
- testEnvironment: 'node',
-};
diff --git a/package.json b/package.json
deleted file mode 100644
index 14bd3aa..0000000
--- a/package.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "name": "typescript-back-template",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "npx jest -i",
- "build": "npx tsc --outDir dist",
- "start": "node dist/src/server.js",
- "postinstall": "npm run build",
- "dev": "npx nodemon --watch \"src/**\" --ext \"ts,json\" --exec \"ts-node src/server.ts\""
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@types/cors": "^2.8.12",
- "@types/express": "^4.17.13",
- "@types/faker": "^5.5.9",
- "@types/jest": "^26.0.24",
- "@types/joi": "^17.2.3",
- "@types/node": "^16.3.3",
- "@types/pg": "^8.6.1",
- "@types/supertest": "^2.0.11",
- "@typescript-eslint/eslint-plugin": "^5.6.0",
- "@typescript-eslint/parser": "^5.6.0",
- "eslint": "^8.4.1",
- "eslint-config-airbnb-base": "^15.0.0",
- "eslint-plugin-import": "^2.25.3",
- "jest": "^27.0.6",
- "nodemon": "^2.0.12",
- "supertest": "^6.1.3",
- "ts-jest": "^27.0.3",
- "ts-node": "^10.1.0",
- "typescript": "^4.3.5"
- },
- "dependencies": {
- "cors": "^2.8.5",
- "dayjs": "^1.10.7",
- "dotenv": "^10.0.0",
- "express": "^4.17.1",
- "faker": "^5.5.3",
- "joi": "^17.5.0",
- "pg": "^8.6.0"
- }
-}
diff --git a/src/app.ts b/src/app.ts
deleted file mode 100644
index 8aa8b51..0000000
--- a/src/app.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import express from 'express';
-import cors from 'cors';
-
-import usersRoute from './routers/usersRoute';
-import questionsRoute from './routers/questionsRoute';
-
-const app = express();
-app.use(cors());
-app.use(express.json());
-
-app.use(questionsRoute);
-app.use(usersRoute);
-
-export default app;
diff --git a/src/controllers/questionsController.ts b/src/controllers/questionsController.ts
deleted file mode 100644
index 987f32e..0000000
--- a/src/controllers/questionsController.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/* eslint-disable consistent-return */
-import { Response, Request } from 'express';
-
-import * as questionsService from '../services/questionsService';
-import { NewQuestionInterface } from '../interfaces/newQuestionInterface';
-import { AnswerQuestionInterface } from '../interfaces/answerQuestionInterface';
-
-export async function newQuestion(req: Request, res: Response) {
- try {
- const { question, student, userClass, tags } = req.body as NewQuestionInterface;
-
- const addNewQuestion = await questionsService.createQuestion(question, student, userClass, tags);
- if (!addNewQuestion) return res.sendStatus(400);
-
- return res.send(addNewQuestion);
- } catch (err) {
- console.log(err);
- res.sendStatus(500);
- }
-}
-
-export async function getUnansweredQuestions(req: Request, res: Response) {
- try {
- const questions = await questionsService.getQuestions();
- if (!questions) return res.sendStatus(404);
-
- return res.send(questions);
- } catch (err) {
- console.log(err);
- res.sendStatus(500);
- }
-}
-
-export async function answerQuestion(req: Request, res: Response) {
- try {
- const { answer } = req.body as AnswerQuestionInterface;
- const questionId = Number(req.params.id);
- const authorization = req.header('Authorization');
- const token = authorization?.replace('Bearer ', '');
-
- const answerAQuestion = await questionsService.answerAQuestion(answer, questionId, token);
- if (answerAQuestion === false) return res.sendStatus(404);
- if (answerAQuestion === null) return res.sendStatus(400);
-
- return res.sendStatus(201);
- } catch (err) {
- console.log(err);
- res.sendStatus(500);
- }
-}
-
-export async function getQuestionById(req: Request, res: Response) {
- try {
- const questionId = Number(req.params.id);
-
- const question = await questionsService.getQuestionById(questionId);
- if (!question) return res.sendStatus(404);
-
- return res.send(question);
- } catch (err) {
- console.log(err);
- res.sendStatus(500);
- }
-}
diff --git a/src/controllers/usersController.ts b/src/controllers/usersController.ts
deleted file mode 100644
index f77125b..0000000
--- a/src/controllers/usersController.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/* eslint-disable consistent-return */
-import { Response, Request } from 'express';
-
-import { UserInterface } from '../interfaces/userInterface';
-import * as usersService from '../services/usersService';
-
-export async function newUser(req: Request, res: Response) {
- try {
- const { name, userClass } = req.body as UserInterface;
-
- const createUser = await usersService.create(name, userClass);
- if (createUser === false) return res.sendStatus(400);
- if (createUser === null) return res.sendStatus(409);
-
- res.status(201).send(createUser);
- } catch (err) {
- console.log(err);
- res.sendStatus(500);
- }
-}
diff --git a/src/database.ts b/src/database.ts
deleted file mode 100644
index 541dc9c..0000000
--- a/src/database.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import './setup';
-import pg from 'pg';
-
-const { Pool } = pg;
-
-const connection = new Pool({
- connectionString: process.env.DATABASE_URL,
- ssl: {
- rejectUnauthorized: false,
- },
-});
-
-export default connection;
diff --git a/src/interfaces/answerQuestionInterface.ts b/src/interfaces/answerQuestionInterface.ts
deleted file mode 100644
index b7acaea..0000000
--- a/src/interfaces/answerQuestionInterface.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface AnswerQuestionInterface{
- answer: string,
-}
-
-export { AnswerQuestionInterface };
diff --git a/src/interfaces/newQuestionInterface.ts b/src/interfaces/newQuestionInterface.ts
deleted file mode 100644
index 0e782e0..0000000
--- a/src/interfaces/newQuestionInterface.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-interface NewQuestionInterface{
- question: string,
- student: string,
- userClass: string,
- tags: string
-}
-
-export { NewQuestionInterface };
diff --git a/src/interfaces/userInterface.ts b/src/interfaces/userInterface.ts
deleted file mode 100644
index aacd138..0000000
--- a/src/interfaces/userInterface.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-interface UserInterface{
- name: string,
- userClass: string,
-}
-
-export { UserInterface };
diff --git a/src/repositories/questionsRepository.ts b/src/repositories/questionsRepository.ts
deleted file mode 100644
index 5207a45..0000000
--- a/src/repositories/questionsRepository.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import '../setup';
-import dayjs from 'dayjs';
-import connection from '../database';
-
-export async function newQuestion(question: string, student: string, userClass: string, tags: string):Promise {
- let classId;
- const now = dayjs().format('YYYY-MM-DD HH:mm');
-
- const classAlreadyRegistered = await connection.query(`
- SELECT *
- FROM classes
- WHERE name=$1
- `, [userClass]);
-
- if (classAlreadyRegistered.rowCount === 0) {
- const result = await connection.query(`
- INSERT INTO classes
- (name)
- VALUES ($1)
- RETURNING id
- `, [userClass]);
- classId = result.rows[0].id;
- } else {
- const result = await connection.query(`
- SELECT id
- FROM classes
- WHERE name=$1
- `, [userClass]);
- classId = result.rows[0].id;
- }
-
- const questionId = await connection.query(`
- INSERT INTO questions
- (question, "classId", student, tags, "submitAt")
- VALUES ($1, $2, $3, $4, $5)
- RETURNING id
- `, [question, classId, student, tags, now]);
- return questionId.rows[0].id;
-}
-
-export async function getUnansweredQuestions() {
- const result = await connection.query(`
- SELECT questions.id, questions.question, questions.student, questions."submitAt",
- classes.name AS class
- FROM questions
- JOIN classes
- ON questions."classId"=classes.id
- WHERE answered=false
- `);
- if (result.rowCount === 0) return false;
- return result.rows;
-}
-
-export async function checkQuestionId(questionId: number):Promise {
- const result = await connection.query(`
- SELECT *
- FROM questions
- WHERE id=$1
- `, [questionId]);
- if (result.rowCount === 0) return false;
- return true;
-}
-
-export async function answerQuestion(answer: string, questionId: number, token: string): Promise {
- const whoAnswer = await connection.query(`
- SELECT *
- FROM students
- WHERE token=$1
- `, [token]);
- if (whoAnswer.rowCount === 0) return false;
-
- const answeredBy = whoAnswer.rows[0].id;
- const now = dayjs().format('YYYY-MM-DD HH:mm');
-
- await connection.query(`
- UPDATE questions
- SET answered=true, "answeredAt"=$1, "answeredBy"=$2, answer=$3
- WHERE id=$4
- `, [now, answeredBy, answer, questionId]);
- return true;
-}
-
-export async function getQuestion(questionId: number) {
- const answered = await connection.query(`
- SELECT questions.*,
- classes.name AS class,
- students.name AS "answeredBy"
- FROM questions
- JOIN classes
- ON questions."classId"=classes.id
- JOIN students
- ON questions."answeredBy"=students.id
- WHERE questions.id=$1
- `, [questionId]);
- if (answered.rowCount !== 0) return answered.rows[0];
-
- const unanswered = await connection.query(`
- SELECT questions.*,
- classes.name AS class
- FROM questions
- JOIN classes
- ON questions."classId"=classes.id
- WHERE questions.id=$1
- AND answered=false
- `, [questionId]);
- return unanswered.rows[0];
-}
diff --git a/src/repositories/usersRepository.ts b/src/repositories/usersRepository.ts
deleted file mode 100644
index 3714089..0000000
--- a/src/repositories/usersRepository.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import '../setup';
-import connection from '../database';
-
-export async function checkName(name: string):Promise {
- const check = await connection.query(`
- SELECT *
- FROM students
- WHERE name=$1
- `, [name]);
- if (check.rowCount === 0) return true;
- return false;
-}
-
-export async function createUser(name: string, userClass: string, token: string):Promise {
- let classId;
-
- const classAlreadyRegistered = await connection.query(`
- SELECT *
- FROM classes
- WHERE name=$1
- `, [userClass]);
-
- if (classAlreadyRegistered.rowCount === 0) {
- const result = await connection.query(`
- INSERT INTO classes
- (name)
- VALUES ($1)
- RETURNING id
- `, [userClass]);
- classId = result.rows[0].id;
- } else {
- classId = classAlreadyRegistered.rows[0].id;
- }
-
- const userToken = await connection.query(`
- INSERT INTO students
- (name, "classId", token)
- VALUES ($1, $2, $3)
- RETURNING token
- `, [name, classId, token]);
- return userToken.rows[0].token;
-}
diff --git a/src/routers/questionsRoute.ts b/src/routers/questionsRoute.ts
deleted file mode 100644
index 62d306f..0000000
--- a/src/routers/questionsRoute.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import express from 'express';
-
-import * as questionsController from '../controllers/questionsController';
-
-const router = express.Router();
-
-router.post('/questions', questionsController.newQuestion);
-router.get('/questions', questionsController.getUnansweredQuestions);
-router.post('/questions/:id', questionsController.answerQuestion);
-router.get('/questions/:id', questionsController.getQuestionById);
-
-export default router;
diff --git a/src/routers/usersRoute.ts b/src/routers/usersRoute.ts
deleted file mode 100644
index eff3e76..0000000
--- a/src/routers/usersRoute.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import express from 'express';
-
-import * as usersController from '../controllers/usersController';
-
-const router = express.Router();
-
-router.post('/users', usersController.newUser);
-
-export default router;
diff --git a/src/schemas/AnswerSchema.ts b/src/schemas/AnswerSchema.ts
deleted file mode 100644
index e649c6a..0000000
--- a/src/schemas/AnswerSchema.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import joi from 'joi';
-
-export const answerSchema = joi.object({
- answer: joi.string().trim().required(),
-});
diff --git a/src/schemas/QuestionSchema.ts b/src/schemas/QuestionSchema.ts
deleted file mode 100644
index 222339d..0000000
--- a/src/schemas/QuestionSchema.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import joi from 'joi';
-
-export const questionSchema = joi.object({
- question: joi.string().trim().required(),
- student: joi.string().trim().required(),
- userClass: joi.string().max(2).pattern(/^[A-Z]{1}[1-9]{1}$/).required(),
- tags: joi.string().trim().required(),
-});
diff --git a/src/schemas/UserSchema.ts b/src/schemas/UserSchema.ts
deleted file mode 100644
index a65174c..0000000
--- a/src/schemas/UserSchema.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import joi from 'joi';
-
-export const userSchema = joi.object({
- name: joi.string().trim().required(),
- userClass: joi.string().max(2).pattern(/^[A-Z]{1}[1-9]{1}$/).required(),
-});
diff --git a/src/server.ts b/src/server.ts
deleted file mode 100644
index 3ffcafb..0000000
--- a/src/server.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import './setup';
-import app from './app';
-
-app.listen(Number(process.env.PORT), () => {
- console.log(`Server is listening on port ${Number(process.env.PORT)}.`);
-});
diff --git a/src/services/questionsService.ts b/src/services/questionsService.ts
deleted file mode 100644
index 5a07750..0000000
--- a/src/services/questionsService.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as questionsRepository from '../repositories/questionsRepository';
-import { answerSchema } from '../schemas/AnswerSchema';
-import { questionSchema } from '../schemas/QuestionSchema';
-
-export async function createQuestion(question: string, student: string, userClass: string, tags: string) {
- const isValid = questionSchema.validate({ question, student, userClass, tags });
- if (isValid.error !== undefined) return false;
-
- const questionId = await questionsRepository.newQuestion(question, student, userClass, tags);
- return {
- id: questionId,
- };
-}
-
-export async function getQuestions() {
- const questions = await questionsRepository.getUnansweredQuestions();
- if (!questions) return false;
- return questions;
-}
-
-export async function answerAQuestion(answer: string, questionId: number, token: string) {
- const checkIfAnwersIsValid = answerSchema.validate({ answer });
- if (checkIfAnwersIsValid.error !== undefined) return null;
-
- const checkIfQuestionExists = await questionsRepository.checkQuestionId(questionId);
- if (!checkIfQuestionExists) return false;
-
- const answerTheQuestion = await questionsRepository.answerQuestion(answer, questionId, token);
- if (!answerTheQuestion) return false;
-
- return true;
-}
-
-export async function getQuestionById(questionId: number) {
- const question = await questionsRepository.getQuestion(questionId);
- if (!question) return false;
- if (question.answered === true) {
- return {
- question: question.question,
- student: question.student,
- class: question.class,
- tags: question.tags,
- answered: question.answered,
- submitAt: question.submitAt,
- answeredAt: question.answeredAt,
- answeredBy: question.answeredBy,
- answer: question.answer,
- };
- }
-
- return {
- question: question.question,
- student: question.student,
- class: question.class,
- tags: question.tags,
- answered: question.answered,
- submitAt: question.submitAt,
- };
-}
diff --git a/src/services/usersService.ts b/src/services/usersService.ts
deleted file mode 100644
index 09fc8a4..0000000
--- a/src/services/usersService.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import faker from 'faker';
-
-import * as usersRepository from '../repositories/usersRepository';
-import { userSchema } from '../schemas/UserSchema';
-
-export async function create(name: string, userClass: string) {
- const isValid = userSchema.validate({ name, userClass });
- if (isValid.error !== undefined) return false;
-
- const nameIsAvailable = await usersRepository.checkName(name);
- if (!nameIsAvailable) return null;
-
- const token = faker.datatype.uuid();
-
- const userToken = await usersRepository.createUser(name, userClass, token);
- return {
- token: userToken,
- };
-}
diff --git a/src/setup.ts b/src/setup.ts
deleted file mode 100644
index d6e605d..0000000
--- a/src/setup.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import dotenv from 'dotenv';
-
-const envFile = process.env.NODE_ENV === 'test' ? '.env.test' : '.env';
-
-dotenv.config({
- path: envFile,
-});
diff --git a/src/tests/factories/questionsFactory.ts b/src/tests/factories/questionsFactory.ts
deleted file mode 100644
index fd4fe48..0000000
--- a/src/tests/factories/questionsFactory.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import faker from 'faker';
-import connection from '../../database';
-
-export async function insertStudent(classId: number) {
- const token = faker.datatype.uuid();
- await connection.query(`
- INSERT INTO students
- (name, "classId", token)
- VALUES ($1, $2, $3)
- RETURNING token
- `, ['Veegata', classId, token]);
- return { token };
-}
-
-export async function insertClass() {
- const newClass = await connection.query(`
- INSERT INTO classes
- (name)
- VALUES ('T3')
- RETURNING id
- `);
- return { classId: newClass.rows[0].id };
-}
-
-export async function insertQuestion() {
- const { classId } = await insertClass();
- const newQuestion = await connection.query(`
- INSERT INTO questions
- (question, "classId", student, tags, "submitAt")
- VALUES ('Uki ta contecendo?', ${classId}, 'Vegata', 'typescript, vida, javascript, java?', '2021-12-12 19:56')
- RETURNING id
- `);
- return {
- questionId: newQuestion.rows[0].id,
- classId,
- };
-}
diff --git a/src/tests/integration/questions.test.ts b/src/tests/integration/questions.test.ts
deleted file mode 100644
index fd6a22d..0000000
--- a/src/tests/integration/questions.test.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-/* eslint-disable no-undef */
-import '../../setup';
-
-import { insertClass, insertQuestion, insertStudent } from '../factories/questionsFactory';
-import { agent, clearDatabase, closeConnection } from '../utils/database';
-
-beforeEach(async () => {
- await clearDatabase();
-});
-
-afterAll(async () => {
- await closeConnection();
-});
-
-describe('POST /questions', () => {
- it('should answer with status 400 when question is empty', async () => {
- const body = {
- question: '',
- student: 'Vegata',
- userClass: 'T3',
- tags: 'typescript, vida, javascript, java?',
- };
- const response = await agent.post('/questions').send(body);
- expect(response.status).toEqual(400);
- });
-
- it('should answer with status 400 when student is empty', async () => {
- const body = {
- question: 'Uki ta contecendo?',
- student: '',
- userClass: 'T3',
- tags: 'typescript, vida, javascript, java?',
- };
- const response = await agent.post('/questions').send(body);
- expect(response.status).toEqual(400);
- });
-
- it('should answer with status 400 when userClass is empty', async () => {
- const body = {
- question: 'Uki ta contecendo?',
- student: 'Vegata',
- userClass: '',
- tags: 'typescript, vida, javascript, java?',
- };
- const response = await agent.post('/questions').send(body);
- expect(response.status).toEqual(400);
- });
-
- it('should answer with status 400 when tags is empty', async () => {
- const body = {
- question: 'Uki ta contecendo?',
- student: 'Vegata',
- userClass: 'T3',
- tags: '',
- };
- const response = await agent.post('/questions').send(body);
- expect(response.status).toEqual(400);
- });
-
- it('should answer with status 400 when userClass is invalid', async () => {
- const body = {
- question: 'Uki ta contecendo?',
- student: 'Vegata',
- userClass: 'T33',
- tags: 'typescript, vida, javascript, java?',
- };
- const response = await agent.post('/questions').send(body);
- expect(response.status).toEqual(400);
- });
-});
-
-describe('GET /questions', () => {
- it('should answer with status 404 when there is no unanswered questions to get', async () => {
- const response = await agent.get('/questions');
- expect(response.status).toEqual(404);
- });
-
- it('should answer with status 200 and when there is no unanswered questions to get', async () => {
- await insertQuestion();
-
- const response = await agent.get('/questions');
- expect(response.status).toEqual(200);
- });
-});
-
-describe('POST /questions/:id', () => {
- it('should answer with status 201 when the answer is posted', async () => {
- const body = {
- answer: 'Ok',
- };
- const { questionId, classId } = await insertQuestion();
-
- const { token } = await insertStudent(classId);
-
- const response = await agent.post(`/questions/${questionId}`).send(body).set('Authorization', `Bearer ${token}`);
- expect(response.status).toEqual(201);
- });
-
- it('should answer with status 404 when the question doesnt exists', async () => {
- const body = {
- answer: 'Ok',
- };
- const { classId } = await insertClass();
-
- const { token } = await insertStudent(classId);
-
- const response = await agent.post('/questions/0').send(body).set('Authorization', `Bearer ${token}`);
- expect(response.status).toEqual(404);
- });
-
- it('should answer with status 400 when the answer is empty', async () => {
- const body = {
- answer: '',
- };
- const { questionId, classId } = await insertQuestion();
-
- const { token } = await insertStudent(classId);
-
- const response = await agent.post(`/questions/${questionId}`).send(body).set('Authorization', `Bearer ${token}`);
- expect(response.status).toEqual(400);
- });
-});
-
-describe('GET /questions/:id', () => {
- it('should answer with status 200 when question is returned', async () => {
- const { questionId, classId } = await insertQuestion();
-
- const { token } = await insertStudent(classId);
-
- const response = await agent.get(`/questions/${questionId}`).set('Authorization', `Bearer ${token}`);
- expect(response.status).toEqual(200);
- });
-
- it('should answer with status 404 when there is not question to return', async () => {
- const { classId } = await insertClass();
-
- const { token } = await insertStudent(classId);
-
- const response = await agent.get('/questions/1').set('Authorization', `Bearer ${token}`);
- expect(response.status).toEqual(404);
- });
-});
diff --git a/src/tests/integration/users.test.ts b/src/tests/integration/users.test.ts
deleted file mode 100644
index 4bdae1c..0000000
--- a/src/tests/integration/users.test.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/* eslint-disable no-undef */
-import '../../setup';
-
-import { agent, clearDatabase, closeConnection } from '../utils/database';
-
-beforeEach(async () => {
- await clearDatabase();
-});
-
-afterAll(async () => {
- await closeConnection();
-});
-
-describe('POST /users', () => {
- it('should answer with status 201 when user is created', async () => {
- const body = {
- name: 'Vegata',
- userClass: 'T3',
- };
- const response = await agent.post('/users').send(body);
- expect(response.status).toEqual(201);
- });
-
- it('should answer with status 409 when user name is already used', async () => {
- const body = {
- name: 'Vegata',
- userClass: 'T3',
- };
- await agent.post('/users').send(body);
- const response = await agent.post('/users').send(body);
- expect(response.status).toEqual(409);
- });
-
- it('should answer with status 400 when name is empty', async () => {
- const body = {
- name: '',
- userClass: 'T3',
- };
- await agent.post('/users').send(body);
- const response = await agent.post('/users').send(body);
- expect(response.status).toEqual(400);
- });
-
- it('should answer with status 400 when userClass is invalid', async () => {
- const body = {
- name: 'Vegata',
- userClass: 'T35',
- };
- await agent.post('/users').send(body);
- const response = await agent.post('/users').send(body);
- expect(response.status).toEqual(400);
- });
-});
diff --git a/src/tests/units/QuestionsService.test.ts b/src/tests/units/QuestionsService.test.ts
deleted file mode 100644
index b6235bd..0000000
--- a/src/tests/units/QuestionsService.test.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-/* eslint-disable no-undef */
-import faker from 'faker';
-
-import * as questionsService from '../../services/questionsService';
-import * as questionsRepository from '../../repositories/questionsRepository';
-
-describe('Questions Service', () => {
- it('Should return id when question is created', async () => {
- const question = faker.random.words();
- const student = faker.name.firstName();
- const userClass = 'T1';
- const tags = faker.random.word();
-
- jest.spyOn(questionsRepository, 'newQuestion').mockImplementationOnce(async () => 1);
-
- const result = await questionsService.createQuestion(question, student, userClass, tags);
- expect(result).toBeTruthy();
- });
-
- it('Should return falsy when question is empty', async () => {
- const question = '';
- const student = faker.name.firstName();
- const userClass = 'T1';
- const tags = faker.random.word();
-
- jest.spyOn(questionsRepository, 'newQuestion').mockImplementationOnce(async () => 1);
-
- const result = await questionsService.createQuestion(question, student, userClass, tags);
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when student is empty', async () => {
- const question = faker.random.words();
- const student = '';
- const userClass = 'T1';
- const tags = faker.random.word();
-
- jest.spyOn(questionsRepository, 'newQuestion').mockImplementationOnce(async () => 1);
-
- const result = await questionsService.createQuestion(question, student, userClass, tags);
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when userClass is empty', async () => {
- const question = faker.random.words();
- const student = faker.name.firstName();
- const userClass = '';
- const tags = faker.random.word();
-
- jest.spyOn(questionsRepository, 'newQuestion').mockImplementationOnce(async () => 1);
-
- const result = await questionsService.createQuestion(question, student, userClass, tags);
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when userClass is invalid', async () => {
- const question = faker.random.words();
- const student = faker.name.firstName();
- const userClass = 'T44';
- const tags = faker.random.word();
-
- jest.spyOn(questionsRepository, 'newQuestion').mockImplementationOnce(async () => 1);
-
- const result = await questionsService.createQuestion(question, student, userClass, tags);
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when tags is empty', async () => {
- const question = faker.random.words();
- const student = faker.name.firstName();
- const userClass = 'T44';
- const tags = '';
-
- jest.spyOn(questionsRepository, 'newQuestion').mockImplementationOnce(async () => 1);
-
- const result = await questionsService.createQuestion(question, student, userClass, tags);
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when there is no unanswered questions to get', async () => {
- jest.spyOn(questionsRepository, 'getUnansweredQuestions').mockImplementationOnce(async () => false);
-
- const result = await questionsService.getQuestions();
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when unanswered questions are returned', async () => {
- jest.spyOn(questionsRepository, 'getUnansweredQuestions').mockImplementationOnce(async () => []);
-
- const result = await questionsService.getQuestions();
- expect(result).toBeTruthy();
- });
-
- it('Should return true when a question is answered', async () => {
- const answer = faker.random.words();
- const questionId = Number(faker.datatype.number());
- const token = faker.datatype.uuid();
-
- jest.spyOn(questionsRepository, 'checkQuestionId').mockImplementationOnce(async () => true);
- jest.spyOn(questionsRepository, 'answerQuestion').mockImplementationOnce(async () => true);
-
- const result = await questionsService.answerAQuestion(answer, questionId, token);
- expect(result).toBe(true);
- });
-
- it('Should return false when an invalid questionId is passed', async () => {
- const answer = faker.random.words();
- const questionId = 0;
- const token = faker.datatype.uuid();
-
- jest.spyOn(questionsRepository, 'checkQuestionId').mockImplementationOnce(async () => false);
- jest.spyOn(questionsRepository, 'answerQuestion').mockImplementationOnce(async () => true);
-
- const result = await questionsService.answerAQuestion(answer, questionId, token);
- expect(result).toBe(false);
- });
-
- it('Should return falsy when answer is empty', async () => {
- const answer = '';
- const questionId = Number(faker.datatype.number());
- const token = faker.datatype.uuid();
-
- jest.spyOn(questionsRepository, 'checkQuestionId').mockImplementationOnce(async () => true);
- jest.spyOn(questionsRepository, 'answerQuestion').mockImplementationOnce(async () => false);
-
- const result = await questionsService.answerAQuestion(answer, questionId, token);
- expect(result).toBeFalsy();
- });
-
- it('Should return false when questionId doesnt exists', async () => {
- const questionId = Number(faker.datatype.number());
-
- jest.spyOn(questionsRepository, 'getQuestion').mockImplementationOnce(async () => false);
-
- const result = await questionsService.getQuestionById(questionId);
- expect(result).toBe(false);
- });
-
- it('Should return truthy when the question is returned', async () => {
- const questionId = Number(faker.datatype.number());
-
- jest.spyOn(questionsRepository, 'getQuestion').mockImplementationOnce(async () => true);
-
- const result = await questionsService.getQuestionById(questionId);
- expect(result).toBeTruthy();
- });
-});
diff --git a/src/tests/units/UsersService.test.ts b/src/tests/units/UsersService.test.ts
deleted file mode 100644
index c7e3ace..0000000
--- a/src/tests/units/UsersService.test.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/* eslint-disable no-undef */
-import faker from 'faker';
-
-import * as usersService from '../../services/usersService';
-import * as usersRepository from '../../repositories/usersRepository';
-
-describe('Users Service', () => {
- it('Should return token when user is created', async () => {
- const name = faker.name.firstName();
- const userClass = 'T1';
- const token = faker.datatype.uuid();
-
- jest.spyOn(usersRepository, 'checkName').mockImplementationOnce(async () => true);
- jest.spyOn(usersRepository, 'createUser').mockImplementationOnce(async () => token);
-
- const result = await usersService.create(name, userClass);
- expect(result).toBeTruthy();
- });
-
- it('Should return falsy when name is empty', async () => {
- const name = faker.name.firstName();
- const userClass = 'T1';
- const token = faker.datatype.uuid();
-
- jest.spyOn(usersRepository, 'checkName').mockImplementationOnce(async () => false);
- jest.spyOn(usersRepository, 'createUser').mockImplementationOnce(async () => token);
-
- const result = await usersService.create(name, userClass);
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when userClass is empty', async () => {
- const name = faker.name.firstName();
- const userClass = '';
- const token = faker.datatype.uuid();
-
- jest.spyOn(usersRepository, 'checkName').mockImplementationOnce(async () => false);
- jest.spyOn(usersRepository, 'createUser').mockImplementationOnce(async () => token);
-
- const result = await usersService.create(name, userClass);
- expect(result).toBeFalsy();
- });
-
- it('Should return falsy when userClass is invalid', async () => {
- const name = faker.name.firstName();
- const userClass = 'T44';
- const token = faker.datatype.uuid();
-
- jest.spyOn(usersRepository, 'checkName').mockImplementationOnce(async () => false);
- jest.spyOn(usersRepository, 'createUser').mockImplementationOnce(async () => token);
-
- const result = await usersService.create(name, userClass);
- expect(result).toBeFalsy();
- });
-});
diff --git a/src/tests/utils/database.ts b/src/tests/utils/database.ts
deleted file mode 100644
index f5add5b..0000000
--- a/src/tests/utils/database.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-import supertest from 'supertest';
-import connection from '../../database';
-import app from '../../app';
-
-export const agent = supertest(app);
-
-export async function clearDatabase() {
- await connection.query('TRUNCATE TABLE questions, students, classes RESTART IDENTITY');
-}
-
-export async function closeConnection() {
- await connection.end();
-}
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index e728be7..0000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "compilerOptions": {
- "noImplicitAny": true,
- "esModuleInterop": true
- }
-}
\ No newline at end of file