-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/api products catalogue #65
Conversation
Please fix linting before we review it. |
from .api_views import ProductViewSet | ||
from rest_framework.routers import DefaultRouter | ||
|
||
router = DefaultRouter() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be a good idea to remove the trailing slashes. My front-end friend recently pointed out that it was easier for them that way.
router = DefaultRouter(trailing_slash=False)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont have preference @knop-k. Your call.
from .models import Product | ||
from .serializers import ProductSerializer | ||
from .filters import ProductFilter | ||
from rest_framework import viewsets | ||
from django_filters.rest_framework import DjangoFilterBackend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PEP8 import order rules not followed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not followed in the whole project. Good pointing out, we need to add something to guard id. Right now, let's ignore.
from django_filters import rest_framework as filters | ||
from .models import Product |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PEP8 import order rules not followed
class Meta: | ||
model = Product | ||
fields = ['id', 'category', 'name', 'price', 'short_description', 'full_description', 'parent_product'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a suggestion: you can add read_only_fields to Meta (with e.g. id
field)
import pytest | ||
from django.urls import reverse | ||
from apps.products_catalogue.models import Category, Product | ||
# pylama:ignore=W0404, W0611 | ||
from apps.users.conftest import api_client, login_url, login_data, user_instance, user_instance_token |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PEP8 import order rules not followed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not followed in the whole project. Good pointing out, we need to add something to guard id. Right now, let's ignore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, needs small tweaks in tests.
from .api_views import ProductViewSet | ||
from rest_framework.routers import DefaultRouter | ||
|
||
router = DefaultRouter() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont have preference @knop-k. Your call.
from .models import Product | ||
from .serializers import ProductSerializer | ||
from .filters import ProductFilter | ||
from rest_framework import viewsets | ||
from django_filters.rest_framework import DjangoFilterBackend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not followed in the whole project. Good pointing out, we need to add something to guard id. Right now, let's ignore.
import pytest | ||
from django.urls import reverse | ||
from apps.products_catalogue.models import Category, Product | ||
# pylama:ignore=W0404, W0611 | ||
from apps.users.conftest import api_client, login_url, login_data, user_instance, user_instance_token |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not followed in the whole project. Good pointing out, we need to add something to guard id. Right now, let's ignore.
…ve and inactive and check the output structure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small changes. Looks good, almost there.
results = response.data.get('results', []) | ||
assert len(results) == 1 | ||
|
||
for product_data in results: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why using loop if there is only one product?
for product_data in results: | |
product_data = results[0] |
- fix indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, it checks that fields are there, but not fields values. Would be good to add values check too.
What I would to is prob create
def assert_active_object(data):
# copy all fields values and compare to data[x] ie:
fields_values = {
"name": "main product"
# ... more fields
}
for key, value in data.items():
assert fields_values[key] == value
And use that function whenever you need to compare active_object with response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jacoor What do you think of this approach:
def assert_active_object(data):
fields_values = {
"name": "main product",
"price": "11.00",
"short_description": "short desc",
"full_description": "full_description",
}
for key, value in data.items():
if key in fields_values:
assert fields_values[key] == value
because I don't want to check for example id or category
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for late response.
For id it would be good to check if field is there, and for category too. Would be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jacoor , I added this to test
"full_description": "full_description", | ||
} | ||
for key, value in data.items(): | ||
if key in fields_values: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove this if.
The goal of the test is to FAIL if something is missing, this is so called "silent failure" - test passes, you expect all good but no, field is not there.
Example: data = {}
Test will pass.
assert 'parent_product' in product_data | ||
product_data = results[0] | ||
|
||
assert 'id' in product_data, "Field 'id' is missing in product data" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would add this assertion to assert_active_object function. This way we will have one assertion in test, which is good practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also enough will be to do
product_data['category'] is not None
As this will cover both cases: missing category or category being None. I would remove error message as in this case it might be confusing.
Tests should be short and concise, as this makes them easier to maintain.
…tive_object function
Hi all!
I am just starting my adventure with DRF so please give me constructive comments on what I could improve/add/change.
I have prepared an API for the product:
In Additionally:
added filtering and pagination
Feel free to ask questions and comment