-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into README-update
- Loading branch information
Showing
14 changed files
with
323 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
from fastapi import APIRouter, status, HTTPException | ||
from settings import Settings | ||
from database import client | ||
from models import Organization, OrganizationResponse | ||
import secrets | ||
import string | ||
from fastapi.encoders import jsonable_encoder | ||
|
||
router = APIRouter(prefix="/organizations", tags=["Organizations"]) | ||
settings = Settings() | ||
|
||
|
||
def generate_random_string(): | ||
return "".join( | ||
[ | ||
secrets.choice(string.ascii_letters + string.digits) | ||
for _ in range(settings.random_string_length) | ||
] | ||
) | ||
|
||
|
||
@router.post("/", response_model=OrganizationResponse) | ||
async def create_organization(organization: Organization): | ||
organization = jsonable_encoder(organization) | ||
|
||
# create an API key | ||
key = generate_random_string() | ||
|
||
# check if API key exists | ||
if (client.quiz.organization.find_one({"key": key})) is None: | ||
organization["key"] = key | ||
new_organization = client.quiz.organization.insert_one(organization) | ||
created_organization = client.quiz.organization.find_one( | ||
{"_id": new_organization.inserted_id} | ||
) | ||
return created_organization | ||
|
||
|
||
@router.get("/authenticate/{api_key}", response_model=OrganizationResponse) | ||
async def check_auth_token(api_key: str): | ||
|
||
if ( | ||
org := client.quiz.organization.find_one( | ||
{"key": api_key}, | ||
) | ||
) is not None: | ||
return org | ||
|
||
raise HTTPException( | ||
status_code=status.HTTP_404_NOT_FOUND, | ||
detail=f"org with key {api_key} not found", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from pydantic import BaseSettings | ||
|
||
|
||
class Settings(BaseSettings): | ||
random_string_length: int = 20 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import unittest | ||
import json | ||
from fastapi.testclient import TestClient | ||
from mongoengine import connect, disconnect | ||
from main import app | ||
from routers import quizzes, sessions | ||
|
||
|
||
class BaseTestCase(unittest.TestCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
connect("mongoenginetest", host="mongomock://127.0.0.1:8000") | ||
cls.client = TestClient(app) | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
disconnect() | ||
|
||
def setUp(self): | ||
self.quiz_data = json.load(open("app/tests/dummy_data/homework_quiz.json")) | ||
# We are currently not providing an endpoint for creating questions and the only way to | ||
# create a question is through the quiz endpoint which is why we are using the quiz endpoint | ||
# to create questions and a quiz | ||
response = self.client.post(quizzes.router.prefix + "/", json=self.quiz_data) | ||
self.quiz = json.loads(response.content) | ||
|
||
|
||
class SessionsBaseTestCase(BaseTestCase): | ||
def setUp(self): | ||
super().setUp() | ||
|
||
# create a session (and thus, session answers as well) for the dummy quiz that we have created | ||
response = self.client.post( | ||
sessions.router.prefix + "/", | ||
json={"quiz_id": self.quiz["_id"], "user_id": 1}, | ||
) | ||
self.session = json.loads(response.content) |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,19 @@ | ||
from fastapi.testclient import TestClient | ||
import unittest | ||
import json | ||
from mongoengine import connect, disconnect | ||
from main import app | ||
from .base import BaseTestCase | ||
|
||
client = TestClient(app) | ||
|
||
|
||
class QuestionsTestCase(unittest.TestCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
connect("mongoenginetest", host="mongomock://127.0.0.1:8000") | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
disconnect() | ||
|
||
class QuestionsTestCase(BaseTestCase): | ||
def setUp(self): | ||
data = open("app/dummy_data/homework_quiz.json") | ||
quiz_data = json.load(data) | ||
# We are currently not providing an endpoint for creating questions and the only way to | ||
# create a question is through the quiz endpoint which is why we are using the quiz endpoint | ||
# to create dummy questions | ||
response = client.post("/quiz/", json=quiz_data) | ||
response = json.loads(response.content) | ||
question = response["question_sets"][0]["questions"][0] | ||
super().setUp() | ||
question = self.quiz["question_sets"][0]["questions"][0] | ||
self.question_id, self.text = question["_id"], question["text"] | ||
|
||
def test_get_question_returns_error_if_id_invalid(self): | ||
response = client.get("/questions/00") | ||
response = self.client.get("/questions/00") | ||
assert response.status_code == 404 | ||
response = response.json() | ||
assert response["detail"] == "Question 00 not found" | ||
|
||
def test_get_question_if_id_valid(self): | ||
response = client.get(f"/questions/{self.question_id}") | ||
response = self.client.get(f"/questions/{self.question_id}") | ||
question = response.json() | ||
assert question["text"] == self.text |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,29 @@ | ||
from fastapi.testclient import TestClient | ||
import unittest | ||
import json | ||
from mongoengine import connect, disconnect | ||
from main import app | ||
from .base import BaseTestCase | ||
from ..routers import quizzes | ||
|
||
client = TestClient(app) | ||
|
||
|
||
class QuizTestCase(unittest.TestCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
connect("mongoenginetest", host="mongomock://127.0.0.1:8000") | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
disconnect() | ||
|
||
class QuizTestCase(BaseTestCase): | ||
def setUp(self): | ||
data = open("app/dummy_data/homework_quiz.json") | ||
self.quiz_data = json.load(data) | ||
response = client.post("/quiz/", json=self.quiz_data) | ||
response = json.loads(response.content) | ||
self.id = response["_id"] | ||
super().setUp() | ||
self.id = self.quiz["_id"] | ||
self.length = len(self.quiz_data["question_sets"][0]["questions"]) | ||
|
||
def test_create_quiz(self): | ||
response = client.post("/quiz/", json=self.quiz_data) | ||
response = self.client.post(quizzes.router.prefix + "/", json=self.quiz_data) | ||
response = json.loads(response.content) | ||
id = response["_id"] | ||
response = client.get(f"/quiz/{id}") | ||
response = self.client.get(f"{quizzes.router.prefix}/{id}") | ||
assert response.status_code == 200 | ||
|
||
def test_get_question_if_id_valid(self): | ||
response = client.get(f"/quiz/{self.id}") | ||
response = self.client.get(f"{quizzes.router.prefix}/{self.id}") | ||
assert response.status_code == 200 | ||
response = response.json() | ||
assert len(response["question_sets"][0]["questions"]) == self.length | ||
|
||
def test_get_quiz_returns_error_if_id_invalid(self): | ||
response = client.get("/quiz/00") | ||
response = self.client.get(f"{quizzes.router.prefix}/00") | ||
assert response.status_code == 404 | ||
response = response.json() | ||
assert response["detail"] == "quiz 00 not found" |
Oops, something went wrong.