Skip to content

Commit

Permalink
Merge pull request #139 from bounswe/practice-app/bug-fix/post-#137
Browse files Browse the repository at this point in the history
Bug-Fix on the external API
  • Loading branch information
canberkboun9 authored May 18, 2022
2 parents 34e7811 + 6dbd477 commit 679716f
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 12 deletions.
5 changes: 2 additions & 3 deletions practice-app/post/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.urls import reverse_lazy
from .models import Post
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout
from crispy_forms.layout import Submit


class PostForm(forms.ModelForm):
Expand All @@ -13,8 +13,7 @@ def __init__(self, *args, **kwargs):
self.helper.form_method = 'POST'
self.helper.form_action = reverse_lazy('post_create')
self.helper.add_input(Submit('submit', 'Create Post'))
#self.helper.layout()


class Meta:
model = Post
fields = ('title','body','category','country')
Expand Down
Binary file removed practice-app/post/static/boun.jpg
Binary file not shown.
3 changes: 0 additions & 3 deletions practice-app/post/templates/post_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ <h6 class="mb-4 pb-3">By filling the blanks below, you can create a post! While
</div>
</div>
</div>
<!-- <button class="btn btn-primary" id="submit-id-submit">
<a href="http://127.0.0.1:8000/">Back</a>
</button> -->
<a class="btn btn-primary" href="http://127.0.0.1:8000/">Go to home page</a>
</div>

Expand Down
3 changes: 3 additions & 0 deletions practice-app/post/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

class TestForms(TestCase):

#creates a category and a user object to test the form
def setUp(self):
self.category = Category.objects.create(
name = 'name',
Expand All @@ -18,6 +19,7 @@ def setUp(self):
email='email'
)

#asserts true if form is valid
def test_post_form_valid_data(self):
form = PostForm(data={
'title': 'title',
Expand All @@ -28,6 +30,7 @@ def test_post_form_valid_data(self):

self.assertTrue(form.is_valid())

#asserts false if form is not valid
def test_post_form_missing_input(self):
self.client.login(username='username', password='password')
form = PostForm(data={})
Expand Down
2 changes: 2 additions & 0 deletions practice-app/post/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

class TestModels(TestCase):

#creates a category, a user, a post and necessary data to be tested.
def setUp(self):

category = Category.objects.create(
Expand Down Expand Up @@ -34,5 +35,6 @@ def setUp(self):

self._post = Post.objects.create(**post_data)

#tests whether model returns the correct field with correct data
def test_str(self):
self.assertEquals(self._post.__str__(), 'title_of_the_model')
3 changes: 3 additions & 0 deletions practice-app/post/tests/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
from django.urls import resolve,reverse
from post.views import poster, index, get, create

#this class tests all urls in the folder /post/urls.py
#checks for every urls corresponding function is matches

class TestUrls(SimpleTestCase):

def test_poster_url_resolves(self):
Expand Down
20 changes: 19 additions & 1 deletion practice-app/post/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

class TestViews(TestCase):

#creates a client to send requests in test
#stores urls of the pages by reverse function
#creates a category, a user, a post, and necessary data to be used in requests
#logs the client in with created user parameters
def setUp(self):
self.client = Client()
self.index_url = reverse('post_index')
Expand Down Expand Up @@ -58,37 +62,51 @@ def setUp(self):
self._post = Post.objects.create(**post_data)

self.client.login(username='username', password='password')


#tests index function with GET functionality
#checks returned status and rendered template
def test_index_GET(self):
response = self.client.get(self.index_url)
self.assertEquals(response.status_code, 200)
self.assertTemplateUsed(response, 'post_index.html')

#tests get function with GET functionality
#checks returned status and rendered template
def test_get_GET(self):
response = self.client.get(self.get_url)
self.assertEquals(response.status_code, 200)
self.assertTemplateUsed(response, 'post_get.html')

#tests create function with POST functionality, success
#checks returned status and rendered template
def test_create_POST_create_post(self):
response = self.client.post(self.create_url, self.ui_data)
self.assertEquals(response.status_code, 200)
self.assertTemplateUsed(response, 'post_create.html')

#tests create function with POST functionality, failure
#checks returned status and rendered template
def test_create_POST_missing_input(self):
response = self.client.post(self.create_url)
self.assertEquals(response.status_code, 200)
self.assertTemplateUsed(response, 'post_notfound.html')

#tests poster function with POST functionality, success
#checks returned status and returned data
def test_poster_POST_create_post(self):
response = self.client.post(self.poster_url, self.data)
self.assertEquals(response.status_code, 201)
self.assertEquals(response.data['title'], 'title_create_data')

#tests poster function with POST functionality, failure
#checks returned status and returned data
def test_poster_POST_missing_input(self):
response = self.client.post(self.poster_url)
self.assertEquals(response.status_code, 400)
self.assertEquals(response.data, 'Missing input')

#tests poster function with GET functionality
#checks returned status and returned data
def test_poster_GET(self):
response = self.client.get(self.poster_url)
self.assertEquals(response.status_code, 200)
Expand Down
56 changes: 51 additions & 5 deletions practice-app/post/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
import re

EXTERNAL_COVID_API_URL = f'https://coronavirus.m.pipedream.net/'
#this is the external API that is used to fetch COVID19 data
EXTERNAL_COVID_API_URL = f'https://api.covid19api.com/summary'

#creates a form
#renders the page for post app
def index(req):
postForm = PostForm()
context = {'form':postForm}
return render(req, 'post_index.html', context)

#calls the API and stores the returned data as response
#then processes tha response
#renders notfound page or createdpost page according to response
def create(req):
response = poster(req).data
if response in ['Missing input', 'Missing category info', 'User should be logged in', 'Category does not exist', 'User does not exist']:
Expand All @@ -29,6 +36,9 @@ def create(req):
context = {'response':post}
return render(req, 'post_create.html', context)

#calls the API and stores the returned data as responses
#then processes the responses
#renders the allposts page with the element of responses
def get(req):
responses = poster(req).data

Expand All @@ -43,47 +53,74 @@ def get(req):
context = {'response':posts}
return render(req, 'post_get.html', context)

#API to GET and POST
@api_view(["GET", "POST"])
def poster(req):

#runs if the call method is GET
#returns all the posts
if req.method == "GET":
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(data=serializer.data)

#runs if the call method is POST
#creates a post
#returns the data of the created post
if req.method == "POST":

#tries to fetch user input
#returns error if fails
try:
title = req.POST['title']
body = req.POST['body']
category = req.POST['category']
except:
return Response('Missing input', status=status.HTTP_400_BAD_REQUEST)

#tries to fetch country info
#converts the first letter of every word to uppercase except the word 'of'
#assigns country as empty string if fails
try:
country = req.POST['country']
country = re.sub("(^|\s)(\S)", convert_into_uppercase, country).replace('Of', 'of')
except:
country = ''

#tries to fetch user info from session
#returns error if fails
try:
user = req.user.id
except:
return Response('User should be logged in', status=status.HTTP_400_BAD_REQUEST)

#double checks
#returns error if category field is empty
if(category == ''): return Response('Missing category info', status=status.HTTP_400_BAD_REQUEST)
#double checks
#returns error if user info is not fetched
if(user == None): return Response('User should be logged in', status=status.HTTP_400_BAD_REQUEST)

#tries to get category id from database
#returns error if fails
try:
p_category = Category.objects.get(pk=category)
except:
return Response('Category does not exist', status=status.HTTP_404_NOT_FOUND)

#tries to get user id from database
#returns error if fails
try:
p_user = User.objects.get(pk=user)
except:
return Response('User does not exist', status=status.HTTP_404_NOT_FOUND)

#initializes covid19 data
covid19 = {}

#if country is succesfully entered
#gets covid19 info from an external API
#if the response from the external API is not empty set, updates covid19 data
if not country == '':
covidInfo = covidApi(country)

Expand All @@ -92,10 +129,12 @@ def poster(req):
'death': covidInfo[1],
'case': covidInfo[0],
}

#if no covid19 info is returned from the external API
#change country field as NotFound instead of giving error
if covid19 == {}:
country = 'NotFound'

#creates the final result of data to be returned
data = {
'title' : title,
'body' : body,
Expand All @@ -105,22 +144,29 @@ def poster(req):
'covid19cases' : covid19
}

#creates a post with corresponding data and returns the data
_post = Post.objects.create(**data)
serializer = PostSerializer(_post, partial=True)
return Response(serializer.data, status=status.HTTP_201_CREATED)

#fetches covid19 data from an external API
#param: country: country name whose data will be fetched
def covidApi(country):
result = requests.get(EXTERNAL_COVID_API_URL).json()
countries = result["rawData"]
countries = result["Countries"]

country_info = [info for info in countries if info["Country_Region"] == country]
country_info = [info for info in countries if info["Country"] == country]

if country_info:
country_info = country_info[0]
return [country_info['Confirmed'], country_info['Deaths']]
return [country_info['NewConfirmed'], country_info['NewDeaths']]

return []

#makes user input case-insensitive
def convert_into_uppercase(a):
return a.group(1) + a.group(2).upper()




Expand Down

0 comments on commit 679716f

Please sign in to comment.