Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions backend_challenge/content
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
https://github.com/vitorfs/bootcamp/blob/master/env.example
https://github.com/vitorfs/bootcamp/blob/master/.travis.yml
https://simpleisbetterthancomplex.com/2015/11/26/package-of-the-week-python-decouple.html
https://docs.djangoproject.com/en/3.1/topics/security/
https://github.com/vitorfs/parsifal/blob/master/parsifal/settings.py
ALLOWED_HOSTS
DB_HOST
DB_NAME
DB_PASSWORD
DB_USER
DEBUG
OIDC_RP_CLIENT_ID
OIDC_RP_CLIENT_SECRET
SECRET_KEY
27 changes: 27 additions & 0 deletions backend_challenge/core/.coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# .coveragerc to control coverage.py
[run]
source = .
omit =
*venv/*
*venv/bin/*
*venv/include/*
*venv/lib/*
*manage.py
*/settings.py
*/local_settings.py
*/tests/*
*apps.py
*migrations/*
*asgi.py
*wsgi.py

*__init__*
*/__pycache__/*
*/site-packages/*
*/distutils/*


[report]
#fail_under = 100
show_missing = True
#skip_covered = True
23 changes: 20 additions & 3 deletions backend_challenge/core/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Generated by Django 3.1.1 on 2020-10-05 04:24
# Generated by Django 3.1.1 on 2021-03-05 22:48

from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion

Expand All @@ -14,14 +15,30 @@ class Migration(migrations.Migration):
]

operations = [
migrations.CreateModel(
name='Customer',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('added', models.DateTimeField(auto_now_add=True)),
('edited', models.DateTimeField(auto_now=True)),
('phone', models.CharField(max_length=13, validators=[django.core.validators.RegexValidator(message="Phone number must be entered in the format '+254234567892'. Up to 12 digits allowed with no", regex='^\\+254\\d{9}$')])),
('code', models.CharField(max_length=15, verbose_name='code')),
('code2', models.CharField(max_length=15, verbose_name='code2')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Order',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('added', models.DateTimeField(auto_now_add=True)),
('edited', models.DateTimeField(auto_now=True)),
('item', models.CharField(max_length=200)),
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('item', models.CharField(max_length=200, verbose_name='item')),
('amount', models.PositiveIntegerField()),
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='orders', to='core.customer')),
],
options={
'ordering': ['-added'],
Expand Down
33 changes: 0 additions & 33 deletions backend_challenge/core/migrations/0002_auto_20201015_0515.py

This file was deleted.

17 changes: 17 additions & 0 deletions backend_challenge/core/migrations/0002_remove_customer_code2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.1.1 on 2021-03-05 23:17

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0001_initial'),
]

operations = [
migrations.RemoveField(
model_name='customer',
name='code2',
),
]
22 changes: 0 additions & 22 deletions backend_challenge/core/migrations/0003_customer_user.py

This file was deleted.

18 changes: 0 additions & 18 deletions backend_challenge/core/migrations/0004_auto_20201028_2244.py

This file was deleted.

18 changes: 0 additions & 18 deletions backend_challenge/core/migrations/0005_auto_20201028_2315.py

This file was deleted.

34 changes: 24 additions & 10 deletions backend_challenge/core/models.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
from django.db import models
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
from django.contrib.auth.models import User
from django.core.validators import RegexValidator

class Customer(models.Model):
phone = models.CharField('phone', max_length=12)

class TimeStampedModel(models.Model):
added = models.DateTimeField(auto_now_add=True)
edited = models.DateTimeField(auto_now=True)

class Meta:
abstract = True

class Customer(TimeStampedModel):
phone= models.CharField(max_length=13,
validators=[
RegexValidator(
regex=r'^\+254\d{9}$',
message="Phone number must be entered in the format '+254234567892'. Up to 12 digits allowed with no"
),
],
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
code= models.CharField('code', max_length=15)

# validationhttps://stackoverflow.com/questions/19130942/whats-the-best-way-to-store-phone-number-in-django-models

def __str__(self):
return self.user.email




class TimeStampedModel(models.Model):
added = models.DateTimeField(auto_now_add=True)
edited = models.DateTimeField(auto_now=True)

class Meta:
abstract = True


class Order(TimeStampedModel):
item = models.CharField(max_length=200, )
amount = models.PositiveIntegerField(default=1)
customer = models.ForeignKey('Customer', on_delete=models.CASCADE)
item = models.CharField('item',max_length=200 )
amount = models.PositiveIntegerField()
customer = models.ForeignKey('Customer',related_name='orders',on_delete=models.CASCADE)

def __str__(self):
return str(self.id)
Expand Down
42 changes: 42 additions & 0 deletions backend_challenge/core/movie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from hypothesis.extra.django import TestCase
import pytest
from hypothesis import strategies as st, given
from django.contrib.auth.models import User
from .models import Order, Customer
from mixer.backend.django import mixer
@pytest.fixture
def api_client():
from rest_framework.test import APIClient
return APIClient()

@pytest.mark.django_db
def test_user_create():
User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
assert User.objects.count() == 1



@pytest.mark.django_db
def test_customer_model():
user=User.objects.create(username="eugine",email="ochungeugine@gmail.com")
customer= Customer.objects.create(user=user,phone=733333)
assert Customer.objects.count() == 1
@pytest.mark.django_db
def test_string_representation():
user=User.objects.create(username="eugine",email="ochungeugine@gmail.com")
customer= Customer.objects.create(user=user,phone=733333)
assert str(customer)=="ochungeugine@gmail.com"

@pytest.mark.django_db
def test_authenticated_user_can_create_new_order(api_client):

data= {
'item': 'books',
'amount': 4,
'customer': self.customer.id
}
response=self.client.post(self.url, data=data)
print(response.data)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Order.objects.count(), 1)

39 changes: 28 additions & 11 deletions backend_challenge/core/serializers.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
from rest_framework import serializers
from .models import Order,Customer
from .models import Order, Customer
from django.contrib.auth.models import User
from rest_framework.exceptions import ValidationError


class CustomerSerializer(serializers.ModelSerializer):
class Meta:

class Meta:
model = Customer
fields = ("phone",)
fields = ("phone", "code")




class OrderSerializer(serializers.ModelSerializer):
customer_phone = serializers.SerializerMethodField()
send_sms=serializers.SerializerMethodField()
customer = CustomerSerializer(read_only=True)

class Meta:
model = Order
fields = ("item", "amount","customer_phone","send_sms")
fields = ("item", "amount","customer")
def validate(self, data):
if data.get('customer') is None:
raise serializers.ValidationError(
'Please Update your profile details'
)

def get_customer_phone(self, obj):
return obj.customer.phone
return data

def get_send_sms(self, obj):
message = f'Dear {obj.customer.user} You have successfully placed an order.Your order ID is {obj.id}.An SMS was sent confirming receipt of your order'
return message

def create(self, validated_data):
request = self.context.get('request', None)
if request is None:
return False

customer=request.user.customer
print(customer)
'''Create a new Customer instance, given the accepted data.'''
return Order.objects.create(**validated_data,customer=customer)
7 changes: 4 additions & 3 deletions backend_challenge/core/tasks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.conf import settings
from celery import shared_task
import africastalking
from.models import Order
username = "sandbox" # use 'sandbox' for development in the test environment
api_key = "c24b10b049468747684e01f846e1a7420e106584c144d187b62d39fe667b6a78"
api_key = settings.AFRICASTALKING_API_KEY
africastalking.initialize(username, api_key)
sms = africastalking.SMS

Expand All @@ -13,10 +14,10 @@ def send_sms(order_id):
Task to send an sms notification when an order is
successfully created.
"""
order = Order.objects.get(id=order_id)
order = Order.objects.select_related('customer').get(id=order_id)

message = f'Dear {order.customer.user} You have successfully placed an order.Your order ID is {order.id}.'
response=sms.send(message,["+254728826517"])
response=sms.send(message,[order.customer.phone])
return response
# sudo service redis-server stop
# $ celery -A backend_challenge worker -l INFO
Expand Down
Loading