diff --git a/dogowner/migrations/0002_test_data.py b/dogowner/migrations/0002_test_data.py index 6b92ffb..f015df2 100644 --- a/dogowner/migrations/0002_test_data.py +++ b/dogowner/migrations/0002_test_data.py @@ -11,11 +11,11 @@ def generate_data(apps, schema_editor): test_data = [ ('user1@address.com', 'testUser1', 'password123', 'dog name', 'first name', 'last name', - 1234567890, 'dog race', 'https://www.google.com/user1', 4, 2, 'M'), + 1234567890, 'dog race', 'https://www.google.com/user1.jpg', 4, 2, 'M'), ('user2@address.com', 'testUser2', 'password123', 'dog name', 'first name', 'last name', - 1234567890, 'dog race', 'https://www.google.com/user2', 3, 1, 'M'), + 1234567890, 'dog race', 'https://www.google.com/user2.jpg', 3, 1, 'M'), ('user3@address.com', 'testUser3', 'password123', 'dog name', 'first name', 'last name', - 1234567890, 'dog race', 'https://www.google.com/user3', 2, 5, 'M'), + 1234567890, 'dog race', 'https://www.google.com/user3.jpg', 2, 5, 'M'), ] with transaction.atomic(): diff --git a/dogowner/migrations/0003_alter_dogowner_dog_picture_url.py b/dogowner/migrations/0003_alter_dogowner_dog_picture_url.py new file mode 100644 index 0000000..544adac --- /dev/null +++ b/dogowner/migrations/0003_alter_dogowner_dog_picture_url.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.3 on 2022-04-12 09:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dogowner', '0002_test_data'), + ] + + operations = [ + migrations.AlterField( + model_name='dogowner', + name='dog_picture_url', + field=models.URLField(blank=True, max_length=1000), + ), + ] diff --git a/dogowner/migrations/0004_test_static_data.py b/dogowner/migrations/0004_test_static_data.py new file mode 100644 index 0000000..ce275f3 --- /dev/null +++ b/dogowner/migrations/0004_test_static_data.py @@ -0,0 +1,97 @@ +from django.db import migrations, transaction + +DOG_IMAGE_URL_LIST = [ + "https://www.akc.org/wp-content/uploads/2019/06/Bohemian-Shepherd.1.jpg", + "https://www.akc.org/wp-content/uploads/2020/01/American-Bulldog-standing-in-three-quarter-view.jpg", + "https://www.akc.org/wp-content/uploads/2017/11/German-Shepherd-Dog-running.jpg", + "https://www.akc.org/wp-content/uploads/2017/11/Greater-Swiss-Mountain-Dog-laying-down-in-the-grass.jpg", + "https://www.akc.org/wp-content/uploads/2017/11/Pembroke-Welsh-Corgi-standing-outdoors-in-the-fall.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-golden-retriever-e1613033782856.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-australian-shepard-e1613033832518.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-cockapoo-e1613033932303.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-shorkie-e1613033958646.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-havanese-e1613033974219.jpg", + "https://static.parade.com/wp-content/uploads/2020/12/" + "medium-sized-dog-breeds-labrador-retriever-e1607905300608.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-shiba-inu-e1613033812725.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-pomsky.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-bichon-frise-e1613033839797.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-american-eskimo-e1613033856106.jpg", + "https://static.parade.com/wp-content/uploads/2021/02/cutest-dog-breeds-papillon.jpg", + "https://www.dogbreedslist.info/uploads/dog-pictures/labrador-retriever-2-2.jpg", + "https://www.dogbreedslist.info/uploads/dog-pictures/golden-retriever-2.jpg", + "https://www.dogbreedslist.info/uploads/dog-pictures/beagle-2.jpg", + "https://www.dogbreedslist.info/uploads/dog-pictures/cavalier-king-charles-spaniel-2.jpg" +] + + +class Migration(migrations.Migration): + dependencies = [ + ('dogowner', '0003_alter_dogowner_dog_picture_url'), + ] + + def generate_data(apps, schema_editor): + from dogowner.models import DogOwner + + static_dog_owners = [ + ('david00@address.com', 'David0', 'password123', "Max", 'David', 'Chen', + 4543837361, "Bohemian Shepherd", DOG_IMAGE_URL_LIST[0], 4, 10.3, 'M'), + ('alex01@address.com', 'Alex1', 'password123', "Cooper", 'Alex', 'Johnson', + 9866708395, "American Bulldog", DOG_IMAGE_URL_LIST[1], 3, 15.2, 'F'), + ('maria02@address.com', 'Maria2', 'password123', "Charlie", 'Maria', 'Williams', + 7889543084, "German Shepherd", DOG_IMAGE_URL_LIST[2], 2, 12.6, 'M'), + ('anna03@address.com', 'Anna3', 'password123', "Teddy", 'Anna', 'Brown', + 8970240485, "Greater Swiss Mountain Dog", DOG_IMAGE_URL_LIST[3], 4, 13.4, 'F'), + ('marco04@address.com', 'Marco4', 'password123', "Bear", 'Marco', 'Jones', + 5027914306, "Pembroke Welsh Corgi", DOG_IMAGE_URL_LIST[4], 3, 11.7, 'M'), + ('antonio05@address.com', 'Antonio', 'password123', "Milo", 'Antonio', 'Garcia', + 7978576075, "Golden Retriever", DOG_IMAGE_URL_LIST[5], 2, 10.3, 'F'), + ('daniel06@address.com', 'Daniel', 'password123', "Bentley", 'Daniel', 'Miller', + 9501530128, "Australian Shepherd", DOG_IMAGE_URL_LIST[6], 4, 12.4, 'M'), + ('laura07@address.com', 'Laura', 'password123', "Ollie", 'Laura', 'Davis', + 7348051295, "Cockapoo", DOG_IMAGE_URL_LIST[7], 3, 11.4, 'F'), + ('jose08@address.com', 'Jose', 'password123', "Buddy", 'Jose', 'Rodriguez', + 2305247264, "Shorkie", DOG_IMAGE_URL_LIST[8], 2, 11.7, 'M'), + ('sandra09@address.com', 'Sandra', 'password123', "Rocky", 'Sandra', 'Martinez', + 1372697623, "Havanese", DOG_IMAGE_URL_LIST[9], 4, 12.9, 'F'), + ('sara10@address.com', 'Sara', 'password123', "Leo", 'Sara', 'Taylor', + 6570894063, "Labrador Retriever", DOG_IMAGE_URL_LIST[10], 3, 9.5, 'M'), + ('carlos11@address.com', 'Carlos', 'password123', "Zeus", 'Carlos', 'White', + 1228907345, "Shiba Inu", DOG_IMAGE_URL_LIST[11], 2, 14.5, 'F'), + ('ana12@address.com', 'Ana', 'password123', "Toby", 'Ana', 'Harris', + 9751508102, "Pomsky", DOG_IMAGE_URL_LIST[12], 4, 15.2, 'M'), + ('michael13@address.com', 'Michael', 'password123', "Ace", 'Michael', 'Ramirez', + 3464456341, "Bichon Frise", DOG_IMAGE_URL_LIST[13], 3, 13.2, 'F'), + ('marie14@address.com', 'Marie', 'password123', "Blue", 'Marie', 'Walker', + 1030010154, "American Eskimo", DOG_IMAGE_URL_LIST[14], 2, 12.8, 'M'), + ('franscesco15@address.com', 'Francesco', 'password123', "Atlas", 'Francesco', 'Robinson', + 7366224214, "Papillon", DOG_IMAGE_URL_LIST[15], 3, 13.4, 'F'), + ('martin16@address.com', 'Martin', 'password123', "Theo", 'Martin', 'Lee', + 2313898126, "Labrador Retriever", DOG_IMAGE_URL_LIST[16], 2, 15.6, 'F'), + ('robert17@address.com', 'Robert', 'password123', "Bruno", 'Robert', 'Thompson', + 7634066063, "Golden Retriever", DOG_IMAGE_URL_LIST[17], 3, 12.7, 'M'), + ('luis18@address.com', 'Luis', 'password123', "Louie", 'Luis', 'Sanchez', + 9029364381, "Beagle", DOG_IMAGE_URL_LIST[18], 2, 11.5, 'F'), + ('tony19@address.com', 'Tony', 'password123', "Koda", 'Tony', 'Clark', + 5190084341, "Cavalier King Charles Spaniel", DOG_IMAGE_URL_LIST[19], 2, 10.6, 'M'), + ] + + with transaction.atomic(): + for (email, username, password, dog_name, first_name, last_name, phone_number, dog_race, dog_picture_url, + dog_age, dog_weight, dog_gender) in static_dog_owners: + DogOwner.create(email=email, + username=username, + password=password, + dog_name=dog_name, + first_name=first_name, + last_name=last_name, + phone_number=phone_number, + dog_race=dog_race, + dog_picture_url=dog_picture_url, + dog_age=dog_age, + dog_weight=dog_weight, + dog_gender=dog_gender) + + operations = [ + migrations.RunPython(generate_data), + ] diff --git a/dogowner/models.py b/dogowner/models.py index 33e149c..562fbe0 100644 --- a/dogowner/models.py +++ b/dogowner/models.py @@ -16,7 +16,7 @@ class DogOwner(models.Model): phone_number = models.IntegerField(null=True, blank=True) dog_name = models.CharField(max_length=MaxLength['DOG_NAME'].value, blank=True) dog_race = models.CharField(max_length=MaxLength['DOG_RACE'].value, blank=True) - dog_picture_url = models.CharField(max_length=MaxLength['DOG_PICTURE_URL'].value, blank=True) + dog_picture_url = models.URLField(max_length=MaxLength['DOG_PICTURE_URL'].value, blank=True) dog_age = models.IntegerField(null=True, blank=True) dog_weight = models.FloatField(null=True, blank=True) dog_gender = models.CharField( @@ -25,7 +25,7 @@ class DogOwner(models.Model): default='UN', blank=True) def __str__(self): - return self.first_name + self.last_name + return self.first_name + ' ' + self.last_name @staticmethod def create(email, username, password, dog_name, diff --git a/dogowner/test_dog_owner.py b/dogowner/test_dog_owner.py index 2735983..924329c 100644 --- a/dogowner/test_dog_owner.py +++ b/dogowner/test_dog_owner.py @@ -12,7 +12,7 @@ LAST_NAME = 'USER' PHONE_NUMBER = 1234567890 DOG_RACE = 'lavrador' -DOG_PICTURE_URL = 'https://www.google.com/' +DOG_PICTURE_URL = "https://www.akc.org/wp-content/uploads/2019/06/Bohemian-Shepherd.1.jpg" DOG_AGE = 10 DOG_WEIGHT = 6 DOG_GENDER = 'M' @@ -59,20 +59,12 @@ def test_duplicate_creation_dog_owner_user(self): def test_dog_owner_user_creation_with_invalid_email(self): with pytest.raises(ValidationError, match="'Enter a valid email address.'", ): - DogOwner.create(email='INVALID_EMAIL', username='testuser02', password=PASSWORD, + DogOwner.create(email='INVALID_EMAIL', username='testuser04', password=PASSWORD, dog_name=DOG_NAME, first_name=FIRST_NAME, last_name=LAST_NAME, phone_number=PHONE_NUMBER, dog_race=DOG_RACE, dog_picture_url=DOG_PICTURE_URL, dog_age=DOG_AGE, dog_weight=DOG_WEIGHT, dog_gender=DOG_GENDER ) - def test_dog_owner_user_creation_with_invalid_dog_picture_url(self): - with pytest.raises(ValidationError, match="Enter a valid URL."): - DogOwner.create(email=EMAIL, username='testuser04', password=PASSWORD, - dog_name=DOG_NAME, first_name=FIRST_NAME, last_name=LAST_NAME, - phone_number=PHONE_NUMBER, dog_race=DOG_RACE, dog_picture_url='NOT_A_URL', - dog_age=DOG_AGE, dog_weight=DOG_WEIGHT, dog_gender=DOG_GENDER - ) - def test_dog_owner_user_creation_with_invalid_phone_as_txt(self): with pytest.raises(ValidationError, match="Invalid phone - phone should be number."): DogOwner.create(email=EMAIL, username='testuser05', password=PASSWORD, @@ -178,3 +170,13 @@ def test_dog_owner_user_creation_with_non_alfa_dog_name(self): phone_number=PHONE_NUMBER, dog_race=DOG_RACE, dog_picture_url=DOG_PICTURE_URL, dog_age=DOG_AGE, dog_weight=DOG_WEIGHT, dog_gender=DOG_GENDER ) + + def test_dog_owner_user_creation_with_url_not_an_image(self): + with pytest.raises(ValidationError, + match="""Invalid image URL - URL should end with '.png', '.jpg' or '.jpeg'."""): + DogOwner.create(email=EMAIL, username='testuser17', password=PASSWORD, + dog_name=DOG_NAME, first_name=FIRST_NAME, last_name=LAST_NAME, + phone_number=PHONE_NUMBER, dog_race=DOG_RACE, + dog_picture_url="https://www.not/an/image.com", + dog_age=DOG_AGE, dog_weight=DOG_WEIGHT, dog_gender=DOG_GENDER + ) diff --git a/dogowner/validators.py b/dogowner/validators.py index 059308c..67b8973 100644 --- a/dogowner/validators.py +++ b/dogowner/validators.py @@ -1,6 +1,6 @@ from django.contrib.auth.models import User from django.core.exceptions import ValidationError -from django.core.validators import URLValidator, validate_email +from django.core.validators import validate_email from enum import Enum @@ -36,7 +36,7 @@ def start_validation(self): self.validate_dog_owner_username_unique() self.validate_dog_gender() validate_email(self.email) - validate_url(self.dog_picture_url) + validate_url_is_image(self.dog_picture_url) validate_phone(self.phone_number) validate_max_length(self.dog_picture_url, MaxLength['DOG_PICTURE_URL'].value, "DOG_PICTURE_URL") for i, s in enumerate([self.first_name, self.last_name, self.dog_name, self.dog_race]): @@ -55,10 +55,10 @@ def validate_dog_gender(self): raise ValidationError("Invalid gender - please choose 'M','F' or 'UN.") -def validate_url(url): - if url: - validator = URLValidator() - validator(url) +def validate_url_is_image(url): + img_extenstion = (".png", ".jpg", ".jpeg") + if not url.endswith(img_extenstion): + raise ValidationError("""Invalid image URL - URL should end with '.png', '.jpg' or '.jpeg'.""") def validate_phone(value):