Skip to content
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

Add publication date to collections #3369

Merged
merged 12 commits into from
Dec 20, 2018
4 changes: 2 additions & 2 deletions saleor/core/templatetags/status.py
Expand Up @@ -68,10 +68,10 @@ def render_page_availability(page):

@register.inclusion_tag('dashboard/includes/_collection_availability.html')
def render_collection_availability(collection):
if collection.is_available:
if collection.is_visible:
label_cls = LABEL_SUCCESS
else:
label_cls = LABEL_DANGER
return {'is_available': collection.is_available,
return {'is_visible': collection.is_visible,
'collection': collection,
'label_cls': label_cls}
6 changes: 3 additions & 3 deletions saleor/dashboard/collection/forms.py
Expand Up @@ -28,9 +28,9 @@ class Meta:
'is_published': pgettext_lazy(
'Collection published toggle',
'Published'),
'published_at': pgettext_lazy(
'Published at which date field',
'Published at'),
'published_date': pgettext_lazy(
'The publication date field, can be a posterior date for a planned publication.',
'Published date'),
'description': pgettext_lazy(
'Description field of a collection',
'Description')}
Expand Down
4 changes: 2 additions & 2 deletions saleor/graphql/product/mutations/products.py
Expand Up @@ -110,8 +110,8 @@ class CollectionInput(graphene.InputObjectType):
description = graphene.String(description='Description of the collection.')
background_image = Upload(description='Background image file.')
seo = SeoInput(description='Search engine optimization fields.')
published_at = graphene.String(
description='Publication date. ISO 8601 standard.')
published_date = graphene.String(
k-brk marked this conversation as resolved.
Show resolved Hide resolved
description='Publication date. ISO 8601 standard.')


class CollectionCreateInput(CollectionInput):
Expand Down
6 changes: 3 additions & 3 deletions saleor/graphql/schema.graphql
Expand Up @@ -408,7 +408,7 @@ type Collection implements Node {
backgroundImage: Image
isPublished: Boolean!
description: String!
publishedAt: Date
publishedDate: Date
}

type CollectionAddProducts {
Expand Down Expand Up @@ -439,7 +439,7 @@ input CollectionCreateInput {
description: String
backgroundImage: Upload
seo: SeoInput
publishedAt: String
publishedDate: String
products: [ID]
}

Expand All @@ -455,7 +455,7 @@ input CollectionInput {
description: String
backgroundImage: Upload
seo: SeoInput
publishedAt: String
publishedDate: String
}

type CollectionRemoveProducts {
Expand Down
17 changes: 0 additions & 17 deletions saleor/menu/migrations/0011_auto_20181130_1540.py

This file was deleted.

18 changes: 18 additions & 0 deletions saleor/product/migrations/0081_auto_20181202_1337.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 5 additions & 7 deletions saleor/product/models.py
Expand Up @@ -435,10 +435,9 @@ class VariantImage(models.Model):
class CollectionQuerySet(models.QuerySet):

def public(self):
today = datetime.datetime.today()
return self.filter(
Q(is_published=True),
Q(published_at__lte=today) | Q(published_at__isnull=True))
Q(published_date__lte=datetime.date.today()) | Q(published_date__isnull=True))
k-brk marked this conversation as resolved.
Show resolved Hide resolved

def visible_to_user(self, user):
has_access_to_all = (
Expand All @@ -457,7 +456,7 @@ class Collection(SeoModel):
upload_to='collection-backgrounds', blank=True, null=True)
is_published = models.BooleanField(default=False)
description = models.TextField(blank=True)
published_at = models.DateField(blank=True, null=True)
published_date = models.DateField(blank=True, null=True)
objects = CollectionQuerySet.as_manager()
translated = TranslationProxy()

Expand All @@ -473,10 +472,9 @@ def get_absolute_url(self):
kwargs={'pk': self.id, 'slug': self.slug})

@property
def is_available(self):
today = datetime.date.today()
return self.is_published and \
(self.published_at is None or self.published_at <= today)
def is_visible(self):
return self.is_published and (
self.published_date is None or self.published_date <= datetime.date.today())


class CollectionTranslation(SeoModelTranslation):
Expand Down
3 changes: 1 addition & 2 deletions saleor/product/views.py
Expand Up @@ -136,11 +136,10 @@ def collection_index(request, slug, pk):
collection = get_object_or_404(collections, id=pk)
if collection.slug != slug:
return HttpResponsePermanentRedirect(collection.get_absolute_url())
is_available = collection.is_available
products = products_for_products_list(user=request.user).filter(
collections__id=collection.id).order_by('name')
product_filter = ProductCollectionFilter(
request.GET, queryset=products, collection=collection)
ctx = get_product_list_context(request, product_filter)
ctx.update({'object': collection, 'is_available': is_available})
ctx.update({'object': collection})
return TemplateResponse(request, 'collection/index.html', ctx)
4 changes: 2 additions & 2 deletions templates/collection/index.html
Expand Up @@ -17,9 +17,9 @@
You are previewing a collection that is not published.
{% endblocktrans %}
</div>
{% elif not is_available %}
{% elif object.is_published and object.published_date is not None %}
k-brk marked this conversation as resolved.
Show resolved Hide resolved
<div class="alert alert-warning" role="alert">
{% blocktrans trimmed with date=object.published_at|date context "Unpublished collection details text" %}
{% blocktrans trimmed with date=object.published_date|date context "Unpublished collection details text" %}
<strong>Warning!</strong>
You are previewing a collection that will become visible on <strong>{{ date }}</strong>.
k-brk marked this conversation as resolved.
Show resolved Hide resolved
{% endblocktrans %}
Expand Down
2 changes: 1 addition & 1 deletion templates/dashboard/collection/detail.html
Expand Up @@ -65,7 +65,7 @@
{{ form.is_published|materializecss }}
</div>
<div class="row">
{{ form.published_at|materializecss }}
{{ form.published_date|materializecss }}
</div>
{% include "dashboard/includes/_google_preview.html" with object=collection form=form %}
</div>
Expand Down
10 changes: 3 additions & 7 deletions templates/dashboard/includes/_collection_availability.html
@@ -1,20 +1,16 @@
{% load i18n %}

<div class="label label-{{ label_cls }}">
{% if is_available %}
{% if is_visible %}
{% trans "Published" context "Collection availability status" %}
{% elif not collection.is_published %}
<div class="label">
{% trans "Hidden" context "Collection availability status" %}
</div>
{% elif collection.published_at %}
{% elif collection.is_published and collection.published_date is not None %}
k-brk marked this conversation as resolved.
Show resolved Hide resolved
<div class="label">
k-brk marked this conversation as resolved.
Show resolved Hide resolved
{% blocktrans with date=collection.published_at context "Collection availability status" %}
{% blocktrans with date=collection.published_date context "Collection availability status" %}
Hidden (will become visible on {{ date }})
k-brk marked this conversation as resolved.
Show resolved Hide resolved
{% endblocktrans %}
</div>
<div class="label">
{% trans "Hidden" context "Collection availability status" %}
</div>
</div>
{% endif %}
25 changes: 12 additions & 13 deletions tests/api/test_collection.py
Expand Up @@ -42,7 +42,6 @@ def test_collections_query(
assert collection_data['slug'] == collection.slug
assert collection_data['description'] == collection.description
assert collection_data['products']['totalCount'] == collection.products.count()

# query all collections only as a staff user with proper permissions
staff_api_client.user.user_permissions.add(permission_manage_products)
response = staff_api_client.post_graphql(query)
Expand All @@ -55,17 +54,17 @@ def test_create_collection(
monkeypatch, staff_api_client, product_list, permission_manage_products):
query = """
mutation createCollection(
$name: String!, $slug: String!, $description: String, $products: [ID], $backgroundImage: Upload!, $isPublished: Boolean!, $publishedAt: String) {
$name: String!, $slug: String!, $description: String, $products: [ID], $backgroundImage: Upload!, $isPublished: Boolean!, $publishedDate: String) {
collectionCreate(
input: {name: $name, slug: $slug, description: $description, products: $products, backgroundImage: $backgroundImage, isPublished: $isPublished, publishedAt: $publishedAt}) {
input: {name: $name, slug: $slug, description: $description, products: $products, backgroundImage: $backgroundImage, isPublished: $isPublished, publishedDate: $publishedDate}) {
collection {
name
slug
description
products {
totalCount
}
publishedAt
publishedDate
}
errors {
field
Expand All @@ -87,11 +86,11 @@ def test_create_collection(
name = 'test-name'
slug = 'test-slug'
description = 'test-description'
published_at = date.today().isoformat()
published_date = date.today().isoformat()
variables = {
'name': name, 'slug': slug, 'description': description,
'products': product_ids, 'backgroundImage': image_name,
'isPublished': True, 'publishedAt': published_at}
'isPublished': True, 'publishedDate': published_date}
body = get_multipart_request_body(query, variables, image_file, image_name)
response = staff_api_client.post_multipart(
body, permissions=[permission_manage_products])
Expand All @@ -100,7 +99,7 @@ def test_create_collection(
assert data['name'] == name
assert data['slug'] == slug
assert data['description'] == description
assert data['publishedAt'] == published_at
assert data['publishedDate'] == published_date
assert data['products']['totalCount'] == len(product_ids)
collection = Collection.objects.get(slug=slug)
assert collection.background_image.file
Expand Down Expand Up @@ -140,14 +139,14 @@ def test_update_collection(
monkeypatch, staff_api_client, collection, permission_manage_products):
query = """
mutation updateCollection(
$name: String!, $slug: String!, $description: String, $id: ID!, $isPublished: Boolean!, $publishedAt: String) {
$name: String!, $slug: String!, $description: String, $id: ID!, $isPublished: Boolean!, $publishedDate: String) {
collectionUpdate(
id: $id, input: {name: $name, slug: $slug, description: $description, isPublished: $isPublished, publishedAt: $publishedAt}) {
id: $id, input: {name: $name, slug: $slug, description: $description, isPublished: $isPublished, publishedDate: $publishedDate}) {
collection {
name
slug
description
publishedAt
publishedDate
}
}
}
Expand All @@ -162,17 +161,17 @@ def test_update_collection(
name = 'new-name'
slug = 'new-slug'
description = 'new-description'
published_at = date.today().isoformat()
published_date = date.today().isoformat()
variables = {
'name': name, 'slug': slug, 'description': description,
'id': to_global_id('Collection', collection.id), 'isPublished': True, 'publishedAt': published_at}
'id': to_global_id('Collection', collection.id), 'isPublished': True, 'publishedDate': published_date}
response = staff_api_client.post_graphql(
query, variables, permissions=[permission_manage_products])
content = get_graphql_content(response)
data = content['data']['collectionUpdate']['collection']
assert data['name'] == name
assert data['slug'] == slug
assert data['publishedAt'] == published_at
assert data['publishedDate'] == published_date
assert mock_create_thumbnails.call_count == 0


Expand Down
9 changes: 0 additions & 9 deletions tests/conftest.py
@@ -1,6 +1,5 @@
from io import BytesIO
from unittest.mock import MagicMock, Mock
from datetime import datetime, timedelta
import pytest

from django.contrib.auth.models import Permission
Expand Down Expand Up @@ -598,14 +597,6 @@ def collection(db):
return collection


@pytest.fixture
def not_yet_available_collection(db):
collection = Collection.objects.create(
name='Collection', slug='collection', is_published=True, published_at=datetime.today() + timedelta(days=1),
description='Test description')
return collection


@pytest.fixture
def draft_collection(db):
collection = Collection.objects.create(
Expand Down
11 changes: 6 additions & 5 deletions tests/test_collection.py
@@ -1,5 +1,5 @@
from django.urls import reverse

from datetime import date, timedelta
from .utils import get_redirect_location


Expand Down Expand Up @@ -33,16 +33,17 @@ def test_collection_not_exists(client):
assert response.status_code == 404


def test_collection_not_published_404(client, draft_collection):
def test_collection_not_published_404(admin_client, client, draft_collection):
k-brk marked this conversation as resolved.
Show resolved Hide resolved
url_kwargs = {'pk': draft_collection.pk, 'slug': draft_collection.slug}
url = reverse('product:collection', kwargs=url_kwargs)
response = client.get(url)
assert response.status_code == 404

def test_collection_not_yet_published(admin_client, client, not_yet_available_collection):
url_kwargs = {'pk': not_yet_available_collection.pk, 'slug': not_yet_available_collection.slug}
url = reverse('product:collection', kwargs=url_kwargs)
draft_collection.is_published = True
draft_collection.published_date = date.today() + timedelta(days=1)
draft_collection.save()
k-brk marked this conversation as resolved.
Show resolved Hide resolved
response = client.get(url)
assert response.status_code == 404

response = admin_client.get(url)
assert response.status_code == 200