Adicionar testes unitários
This commit is contained in:
parent
88f0ff9800
commit
8e8d9237b7
|
@ -1,4 +1,4 @@
|
||||||
__pycache__/
|
__pycache__/
|
||||||
venv/
|
venv/
|
||||||
pyrightconfig.json
|
pyrightconfig.json
|
||||||
database.db
|
*.db
|
||||||
|
|
|
@ -18,6 +18,12 @@ Inicie o servidor de desenvolvimento:
|
||||||
flask run
|
flask run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Rodando Testes
|
||||||
|
No diretório **raíz**:
|
||||||
|
```
|
||||||
|
python3 -m api.tests
|
||||||
|
```
|
||||||
|
|
||||||
Por padrão o servidor tem sua interface em `http://localhost:5000`.
|
Por padrão o servidor tem sua interface em `http://localhost:5000`.
|
||||||
|
|
||||||
# Desenvolvimento
|
# Desenvolvimento
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/python3
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from flask_marshmallow import Marshmallow
|
from flask_marshmallow import Marshmallow
|
||||||
|
@ -10,6 +9,4 @@ db = SQLAlchemy(app)
|
||||||
ma = Marshmallow(app)
|
ma = Marshmallow(app)
|
||||||
Migrate(app, db)
|
Migrate(app, db)
|
||||||
|
|
||||||
import api.models.trainer
|
|
||||||
import api.models.pokemon_owned
|
|
||||||
import api.routes.routes
|
import api.routes.routes
|
||||||
|
|
|
@ -3,15 +3,15 @@ from api.views import trainer, pokemon_owned, helper, errors
|
||||||
from flask import request
|
from flask import request
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
@app.route("/trainer/<int:trainerId>/", methods=["GET"])
|
@app.route("/trainer/<int:trainerId>", methods=["GET"])
|
||||||
def route_get_trainer(trainerId):
|
def route_get_trainer(trainerId):
|
||||||
return trainer.get_trainer(trainerId)
|
return trainer.get_trainer(trainerId)
|
||||||
|
|
||||||
@app.route("/trainer/", methods=["GET"])
|
@app.route("/trainer", methods=["GET"])
|
||||||
def route_get_trainers():
|
def route_get_trainers():
|
||||||
return trainer.get_trainers()
|
return trainer.get_trainers()
|
||||||
|
|
||||||
@app.route("/trainer/", methods=["POST"])
|
@app.route("/trainer", methods=["POST"])
|
||||||
def route_create_trainer():
|
def route_create_trainer():
|
||||||
return trainer.post_trainer()
|
return trainer.post_trainer()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,360 @@
|
||||||
|
#!/bin/python3
|
||||||
|
from api.app import app, db
|
||||||
|
from api.models.trainer import Trainer
|
||||||
|
from api.models.pokemon_owned import PokemonOwned
|
||||||
|
from flask_testing import TestCase
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class MainTestCase(TestCase):
|
||||||
|
|
||||||
|
def create_app(self):
|
||||||
|
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///testing.db"
|
||||||
|
db.drop_all()
|
||||||
|
db.create_all()
|
||||||
|
trainers = (
|
||||||
|
Trainer(
|
||||||
|
nickname="jose",
|
||||||
|
first_name="José",
|
||||||
|
last_name="da Silva",
|
||||||
|
email="josedasilva.2021@gmail.com",
|
||||||
|
password="1234",
|
||||||
|
team="Team Valor"
|
||||||
|
),
|
||||||
|
Trainer(
|
||||||
|
nickname="joao",
|
||||||
|
first_name="João",
|
||||||
|
last_name="Oliveira",
|
||||||
|
email="joaooliveira@hotmail.com",
|
||||||
|
password="senha",
|
||||||
|
team="Team Instinct"
|
||||||
|
),
|
||||||
|
Trainer(
|
||||||
|
nickname="ricardo",
|
||||||
|
first_name="Ricardo",
|
||||||
|
last_name="Teixeira",
|
||||||
|
email="ricardo.teixeira@gmail.com",
|
||||||
|
password="ricardo",
|
||||||
|
team="Team Mystic"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
pokemons = (
|
||||||
|
PokemonOwned(
|
||||||
|
name="Fluffy",
|
||||||
|
level=1,
|
||||||
|
pokemon_id=12,
|
||||||
|
trainer_id=1
|
||||||
|
),
|
||||||
|
PokemonOwned(
|
||||||
|
name="Dinossauro",
|
||||||
|
level=1,
|
||||||
|
pokemon_id=2,
|
||||||
|
trainer_id=1
|
||||||
|
),
|
||||||
|
PokemonOwned(
|
||||||
|
name="Outro",
|
||||||
|
level=1,
|
||||||
|
pokemon_id=4,
|
||||||
|
trainer_id=1
|
||||||
|
),
|
||||||
|
)
|
||||||
|
db.session.add_all(trainers)
|
||||||
|
db.session.add_all(pokemons)
|
||||||
|
db.session.commit()
|
||||||
|
self.client = app.test_client()
|
||||||
|
return app
|
||||||
|
|
||||||
|
def test_post_trainer(self):
|
||||||
|
trainer = {
|
||||||
|
"nickname": "rodrigro",
|
||||||
|
"first_name": "Ricardo",
|
||||||
|
"last_name": "Lopes",
|
||||||
|
"email": "rlopes@outlook.com",
|
||||||
|
"password": "dummy",
|
||||||
|
"team": "Team Mystic"
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer", json=trainer, follow_redirects=True)
|
||||||
|
self.assert_status(response, 201)
|
||||||
|
self.assertEqual(trainer["email"], response.get_json()["email"])
|
||||||
|
|
||||||
|
def test_post_trainer_duplicate(self):
|
||||||
|
trainer = {
|
||||||
|
"nickname": "julio",
|
||||||
|
"first_name": "Julio",
|
||||||
|
"last_name": "Sobreiro",
|
||||||
|
"email": "julho.sob@yahoo.com",
|
||||||
|
"password": "0987",
|
||||||
|
"team": "Team Mystic"
|
||||||
|
}
|
||||||
|
self.client.post("/trainer", json=trainer, follow_redirects=True)
|
||||||
|
response = self.client.post("/trainer", json=trainer, follow_redirects=True)
|
||||||
|
self.assert_status(response, 409)
|
||||||
|
|
||||||
|
def test_post_trainer_invalid_team(self):
|
||||||
|
trainer = {
|
||||||
|
"nickname": "cesar",
|
||||||
|
"first_name": "Cesar",
|
||||||
|
"last_name": "Pereira",
|
||||||
|
"email": "cesereira@gmail.com",
|
||||||
|
"password": "04031994",
|
||||||
|
"team": "Team Inventado"
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer", json=trainer, follow_redirects=True)
|
||||||
|
self.assert_400(response)
|
||||||
|
|
||||||
|
def test_post_trainer_missing_fields(self):
|
||||||
|
trainer = {}
|
||||||
|
response = self.client.post("/trainer", json=trainer, follow_redirects=True)
|
||||||
|
self.assert_400(response)
|
||||||
|
|
||||||
|
def test_authenticate(self):
|
||||||
|
login = {
|
||||||
|
"email": "josedasilva.2021@gmail.com",
|
||||||
|
"password": "1234",
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"id", response.data)
|
||||||
|
self.assertIn(b"token", response.data)
|
||||||
|
|
||||||
|
def test_authenticate_wrong(self):
|
||||||
|
login = {
|
||||||
|
"email": "josedasilva.2021@gmail.com",
|
||||||
|
"password": "wrong_password",
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_401(response)
|
||||||
|
|
||||||
|
def test_authenticate_not_found(self):
|
||||||
|
login = {
|
||||||
|
"email": "notrainer@withemail.com",
|
||||||
|
"password": "dummy_password",
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_401(response)
|
||||||
|
|
||||||
|
def test_authenticate_no_login(self):
|
||||||
|
login = {}
|
||||||
|
response = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_401(response)
|
||||||
|
|
||||||
|
def test_get_trainers(self):
|
||||||
|
response = self.client.get("/trainer", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"jose", response.data)
|
||||||
|
self.assertIn(b"joao", response.data)
|
||||||
|
self.assertIn(b"ricardo", response.data)
|
||||||
|
|
||||||
|
def test_get_trainer_by_nickname(self):
|
||||||
|
response = self.client.get("/trainer?nickname=jose", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"jose", response.data)
|
||||||
|
|
||||||
|
def test_get_trainer_by_nickname_not_found(self):
|
||||||
|
response = self.client.get("/trainer?nickname=somerandomnickname", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertEqual(response.data, b"[]")
|
||||||
|
|
||||||
|
def test_get_trainer_by_nickname_contains(self):
|
||||||
|
response = self.client.get("/trainer?nickname_contains=jo", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"jose", response.data)
|
||||||
|
self.assertIn(b"joao", response.data)
|
||||||
|
|
||||||
|
def test_get_trainer_by_nickname_contains_limit(self):
|
||||||
|
response = self.client.get("/trainer?nickname_contains=jo&limit=1", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"jose", response.data)
|
||||||
|
self.assertNotIn(b"joao", response.data)
|
||||||
|
|
||||||
|
def test_get_trainer_by_nickname_contains_offset(self):
|
||||||
|
response = self.client.get("/trainer?nickname_contains=jo&offset=1", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertNotIn(b"jose", response.data)
|
||||||
|
self.assertIn(b"joao", response.data)
|
||||||
|
|
||||||
|
def test_get_trainer_by_id(self):
|
||||||
|
response = self.client.get("/trainer/1", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"jose", response.data)
|
||||||
|
self.assertNotIn(b"joao", response.data)
|
||||||
|
|
||||||
|
def test_get_trainer_by_id_not_found(self):
|
||||||
|
response = self.client.get("/trainer/1000", follow_redirects=True)
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
def test_get_pokemons(self):
|
||||||
|
response = self.client.get("/trainer/1/pokemon", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"Fluffy", response.data)
|
||||||
|
self.assertIn(b"Dinossauro", response.data)
|
||||||
|
self.assertIn(b"Outro", response.data)
|
||||||
|
self.assertIn(b"pokemon_data", response.data)
|
||||||
|
|
||||||
|
def test_get_pokemons_trainer_not_found(self):
|
||||||
|
response = self.client.get("/trainer/1000/pokemon", follow_redirects=True)
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
def test_get_pokemons_limit(self):
|
||||||
|
response = self.client.get("/trainer/1/pokemon?limit=1", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertIn(b"Fluffy", response.data)
|
||||||
|
self.assertNotIn(b"Dinossauro", response.data)
|
||||||
|
self.assertNotIn(b"Outro", response.data)
|
||||||
|
|
||||||
|
def test_get_pokemons_offset(self):
|
||||||
|
response = self.client.get("/trainer/1/pokemon?offset=1", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertNotIn(b"Fluffy", response.data)
|
||||||
|
self.assertIn(b"Dinossauro", response.data)
|
||||||
|
self.assertIn(b"Outro", response.data)
|
||||||
|
|
||||||
|
def test_get_pokemon_by_id(self):
|
||||||
|
response = self.client.get("/trainer/1/pokemon/2", follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
self.assertNotIn(b"Fluffy", response.data)
|
||||||
|
self.assertIn(b"Dinossauro", response.data)
|
||||||
|
self.assertNotIn(b"Outro", response.data)
|
||||||
|
self.assertIn(b"pokemon_data", response.data)
|
||||||
|
|
||||||
|
def test_get_pokemon_by_id_not_found(self):
|
||||||
|
response = self.client.get("/trainer/1/pokemon/1000", follow_redirects=True)
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
def test_post_pokemon_no_auth(self):
|
||||||
|
data = {
|
||||||
|
"name": "Dummy",
|
||||||
|
"level": 9,
|
||||||
|
"pokemon_id": 12
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/2/pokemon", json=data, follow_redirects=True)
|
||||||
|
self.assert_401(response)
|
||||||
|
|
||||||
|
def test_post_pokemon(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
data = {
|
||||||
|
"name": "Dummy",
|
||||||
|
"level": 2,
|
||||||
|
"pokemon_id": 12
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/2/pokemon", json=data, headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_status(response, 201)
|
||||||
|
self.assertIn(b"Dummy", response.data)
|
||||||
|
self.assertIn(b"pokemon_data", response.data)
|
||||||
|
|
||||||
|
def test_post_pokemon_trainer_not_found(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
data = {
|
||||||
|
"name": "Dummy",
|
||||||
|
"level": 2,
|
||||||
|
"pokemon_id": 12
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/200/pokemon", json=data, headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_403(response)
|
||||||
|
|
||||||
|
# adicionando pokemon pra outro trainer
|
||||||
|
def test_post_pokemon_forbidden(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
data = {
|
||||||
|
"name": "Dummy",
|
||||||
|
"level": 2,
|
||||||
|
"pokemon_id": 12
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/1/pokemon", json=data, headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_403(response)
|
||||||
|
|
||||||
|
def test_post_pokemon_no_species(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
data = {
|
||||||
|
"name": "Dumb",
|
||||||
|
"level": 2,
|
||||||
|
"pokemon_id": 12000
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/2/pokemon", json=data, headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_404(response)
|
||||||
|
|
||||||
|
def test_delete_pokemon_trainer_not_found(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
response = self.client.delete("/trainer/200/pokemon/1", headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_403(response)
|
||||||
|
|
||||||
|
def test_delete_pokemon_no_auth(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
data = {
|
||||||
|
"name": "Dummier",
|
||||||
|
"level": 2,
|
||||||
|
"pokemon_id": 12
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/2/pokemon", json=data, headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_status(response, 201)
|
||||||
|
response = self.client.delete("/trainer/2/pokemon/{}".format(response.get_json()["id"]), follow_redirects=True)
|
||||||
|
self.assert_401(response)
|
||||||
|
|
||||||
|
def test_delete_pokemon_not_found(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
response = self.client.delete("/trainer/2/pokemon/1000", headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_404(response)
|
||||||
|
|
||||||
|
def test_delete_pokemon(self):
|
||||||
|
login = {
|
||||||
|
"email": "joaooliveira@hotmail.com",
|
||||||
|
"password": "senha",
|
||||||
|
}
|
||||||
|
auth = self.client.post("/trainer/authenticate", json=login, follow_redirects=True)
|
||||||
|
self.assert_200(auth)
|
||||||
|
token = auth.get_json()["token"]
|
||||||
|
data = {
|
||||||
|
"name": "Dummier",
|
||||||
|
"level": 2,
|
||||||
|
"pokemon_id": 12
|
||||||
|
}
|
||||||
|
response = self.client.post("/trainer/2/pokemon", json=data, headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_status(response, 201)
|
||||||
|
response = self.client.delete("/trainer/2/pokemon/{}".format(response.get_json()["id"]), headers={"Authorization":token}, follow_redirects=True)
|
||||||
|
self.assert_200(response)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
|
@ -21,4 +21,4 @@ def ForbiddenError(message):
|
||||||
return error(5, "ForbiddenError", message, http_code=403)
|
return error(5, "ForbiddenError", message, http_code=403)
|
||||||
|
|
||||||
def FetchError(message):
|
def FetchError(message):
|
||||||
return error(6, "FetchError", message, http_code=500)
|
return error(6, "FetchError", message, http_code=404)
|
||||||
|
|
|
@ -12,16 +12,17 @@ class HTTPError(Exception):
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
class NotFound(Exception):
|
class NotFound(Exception):
|
||||||
pass
|
def __init__(self, message):
|
||||||
|
self.message = message
|
||||||
|
|
||||||
def get_or_not_found(callback):
|
def get_or_not_found(callback):
|
||||||
try:
|
try:
|
||||||
resource = callback()
|
resource = callback()
|
||||||
if resource is None:
|
if resource is None:
|
||||||
raise NotFound()
|
raise NotFound("Resource not found")
|
||||||
return resource
|
return resource
|
||||||
except:
|
except:
|
||||||
raise NotFound()
|
raise NotFound("Resource not found")
|
||||||
|
|
||||||
def get_trainer_fail(id):
|
def get_trainer_fail(id):
|
||||||
return get_or_not_found(lambda : Trainer.query.get(id))
|
return get_or_not_found(lambda : Trainer.query.get(id))
|
||||||
|
@ -50,21 +51,25 @@ def token_required(f):
|
||||||
return f(trainer, *args, **kwargs)
|
return f(trainer, *args, **kwargs)
|
||||||
return decorated
|
return decorated
|
||||||
|
|
||||||
|
# helpers internos
|
||||||
|
def cant_fetch_error(pokemon):
|
||||||
|
raise NotFound("Could not fetch data for pokemon with id {}".format(pokemon.pokemon_id))
|
||||||
|
|
||||||
# seguintes funções puxam informações da pokeapi
|
# seguintes funções puxam informações da pokeapi
|
||||||
def set_pokemon_data(pokemon):
|
def set_pokemon_data(pokemon):
|
||||||
try:
|
try:
|
||||||
response = requests.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id))
|
response = requests.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id))
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))
|
cant_fetch_error(pokemon)
|
||||||
pokemon.pokemon_data = json.loads(response.text)
|
pokemon.pokemon_data = json.loads(response.text)
|
||||||
except:
|
except:
|
||||||
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))
|
cant_fetch_error(pokemon)
|
||||||
|
|
||||||
async def async_set_pokemon_data(session, pokemon):
|
async def async_set_pokemon_data(session, pokemon):
|
||||||
try:
|
try:
|
||||||
response = await session.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id))
|
response = await session.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id))
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))
|
cant_fetch_error(pokemon)
|
||||||
pokemon.pokemon_data = json.loads(await response.text())
|
pokemon.pokemon_data = json.loads(await response.text())
|
||||||
except:
|
except:
|
||||||
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))
|
cant_fetch_error(pokemon)
|
||||||
|
|
|
@ -4,7 +4,7 @@ from .parse_args import parse_limit, parse_offset, ParsingException, parse_json_
|
||||||
from .errors import ParsingError, FetchError, ConflictingResources
|
from .errors import ParsingError, FetchError, ConflictingResources
|
||||||
from .helper import *
|
from .helper import *
|
||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from asyncio import create_task, gather
|
import asyncio
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
|
|
||||||
def post_pokemon_owned(trainer_id):
|
def post_pokemon_owned(trainer_id):
|
||||||
|
@ -30,7 +30,7 @@ def post_pokemon_owned(trainer_id):
|
||||||
|
|
||||||
db.session.add(pokemon)
|
db.session.add(pokemon)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except HTTPError as e:
|
except NotFound as e:
|
||||||
return FetchError(e.message)
|
return FetchError(e.message)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
return ConflictingResources("Trainer already has another pokemon with the same name")
|
return ConflictingResources("Trainer already has another pokemon with the same name")
|
||||||
|
@ -54,13 +54,21 @@ async def get_pokemons_owned(trainer_id):
|
||||||
async with ClientSession() as session:
|
async with ClientSession() as session:
|
||||||
tasks = []
|
tasks = []
|
||||||
for pokemon in pokemons:
|
for pokemon in pokemons:
|
||||||
task = create_task(async_set_pokemon_data(session, pokemon))
|
task = asyncio.create_task(async_set_pokemon_data(session, pokemon))
|
||||||
tasks.append(task)
|
tasks.append(task)
|
||||||
try:
|
try:
|
||||||
await gather(*tasks)
|
await asyncio.gather(*tasks)
|
||||||
except HTTPError as e:
|
except NotFound as e:
|
||||||
|
for task in tasks:
|
||||||
|
task.cancel()
|
||||||
return FetchError(e.message)
|
return FetchError(e.message)
|
||||||
|
|
||||||
|
# workaround pra bug do aiohttp, que pode gerar avisos de conexões abertas
|
||||||
|
# ver documentação: https://docs.aiohttp.org/en/stable/client_advanced.html#graceful-shutdown
|
||||||
|
# será arrumado na versão 4.0.0, que ainda não saiu
|
||||||
|
# issue no github: https://github.com/aio-libs/aiohttp/issues/1925
|
||||||
|
await asyncio.sleep(0.250)
|
||||||
|
|
||||||
return pokemon_owned_schemas.dumps(pokemons)
|
return pokemon_owned_schemas.dumps(pokemons)
|
||||||
|
|
||||||
def get_pokemon_owned(trainer_id, pokemon_id):
|
def get_pokemon_owned(trainer_id, pokemon_id):
|
||||||
|
@ -73,6 +81,8 @@ def get_pokemon_owned(trainer_id, pokemon_id):
|
||||||
return "", 404
|
return "", 404
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
return FetchError(e.message)
|
return FetchError(e.message)
|
||||||
|
except NotFound as e:
|
||||||
|
return ParsingError(e.message)
|
||||||
|
|
||||||
def delete_pokemon_owned(trainer, pokemon_id):
|
def delete_pokemon_owned(trainer, pokemon_id):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -11,7 +11,10 @@ import jwt
|
||||||
|
|
||||||
def get_trainer(id):
|
def get_trainer(id):
|
||||||
try:
|
try:
|
||||||
return trainer_schema.dump(Trainer.query.get(id))
|
trainer = Trainer.query.get(id)
|
||||||
|
if trainer is None:
|
||||||
|
return ("", 404)
|
||||||
|
return trainer_schema.dump(trainer)
|
||||||
except:
|
except:
|
||||||
return ("", 404)
|
return ("", 404)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
Flask_SQLAlchemy==2.5.1
|
|
||||||
requests==2.26.0
|
|
||||||
aiohttp==3.7.4.post0
|
|
||||||
Werkzeug==2.0.2
|
Werkzeug==2.0.2
|
||||||
Flask==2.0.2
|
Flask_SQLAlchemy==2.5.1
|
||||||
SQLAlchemy==1.4.25
|
|
||||||
Flask_Migrate==3.1.0
|
|
||||||
flask_marshmallow==0.14.0
|
flask_marshmallow==0.14.0
|
||||||
|
Flask_Migrate==3.1.0
|
||||||
|
Flask==2.0.2
|
||||||
|
requests==2.26.0
|
||||||
|
Flask_Testing==0.8.1
|
||||||
|
SQLAlchemy==1.4.25
|
||||||
|
aiohttp==3.7.4.post0
|
||||||
PyJWT==2.3.0
|
PyJWT==2.3.0
|
||||||
|
|
Loading…
Reference in New Issue