diff --git a/kfet/tests/test_views.py b/kfet/tests/test_views.py index 41ed8b5c..5877044e 100644 --- a/kfet/tests/test_views.py +++ b/kfet/tests/test_views.py @@ -12,7 +12,7 @@ from ..config import kfet_config from ..models import ( Account, Article, ArticleCategory, Checkout, CheckoutStatement, Inventory, InventoryArticle, Operation, OperationGroup, Order, OrderArticle, Supplier, - SupplierArticle, Transfer, TransferGroup, + SupplierArticle, TransferGroup, ) from .testcases import ViewTestCaseMixin from .utils import create_team, create_user, get_perms @@ -248,6 +248,26 @@ class AccountReadViewTests(ViewTestCaseMixin, TestCase): r = client.get(self.url) self.assertEqual(r.status_code, 200) + def test_json(self): + r = self.client.get(self.url, {'format': 'json'}) + + self.assertEqual(r.status_code, 200) + + content = json.loads(r.content.decode('utf-8')) + + expected = { + 'name': 'first last', + 'trigramme': '001', + 'balance': '0.00', + } + self.assertDictContainsSubset(expected, content) + + self.assertSetEqual(set(content.keys()), set([ + 'id', 'trigramme', 'first_name', 'last_name', 'name', 'email', + 'is_cof', 'promo', 'balance', 'is_frozen', 'departement', + 'nickname', + ])) + class AccountUpdateViewTests(ViewTestCaseMixin, TestCase): url_name = 'kfet.account.update' @@ -746,18 +766,53 @@ class CheckoutReadViewTests(ViewTestCaseMixin, TestCase): def setUp(self): super().setUp() + self.checkout = Checkout.objects.create( name='Checkout', created_by=self.accounts['team'], - valid_from=self.now, - valid_to=self.now + timedelta(days=5), + valid_from=datetime(2018, 1, 12, 16, 20, tzinfo=timezone.utc), + valid_to=datetime(2018, 1, 17, 16, 20, tzinfo=timezone.utc), ) + # TODO: This statement is currently created by CheckoutCreate view, it + # should rather be done in Checkout.save(). + with mock.patch('django.utils.timezone.now') as mock_now: + mock_now.return_value = ( + datetime(2018, 1, 12, 16, 20, tzinfo=timezone.utc)) + self.checkout.statements.create( + balance_new=0, balance_old=0, amount_taken=0, + by=self.accounts['team'], + ) + def test_ok(self): r = self.client.get(self.url) self.assertEqual(r.status_code, 200) self.assertEqual(r.context['checkout'], self.checkout) + def test_json(self): + r = self.client.get(self.url, { + 'format': 'json', + 'last_statement': '1', + }) + + self.assertEqual(r.status_code, 200) + content = json.loads(r.content.decode('utf-8')) + + self.assertEqual(content, { + 'id': self.checkout.pk, + 'name': 'Checkout', + 'balance': '0.00', + 'valid_from': '2018-01-12T16:20:00Z', + 'valid_to': '2018-01-17T16:20:00Z', + 'laststatement': { + 'id': self.checkout.statements.all()[0].pk, + 'at': '2018-01-12T16:20:00Z', + 'balance_new': '0.00', + 'balance_old': '0.00', + 'by': str(self.accounts['team']), + }, + }) + class CheckoutUpdateViewTests(ViewTestCaseMixin, TestCase): url_name = 'kfet.checkout.update' @@ -1406,46 +1461,6 @@ class KPsulViewTests(ViewTestCaseMixin, TestCase): self.assertEqual(r.status_code, 200) -class KPsulCheckoutDataViewTests(ViewTestCaseMixin, TestCase): - url_name = 'kfet.kpsul.checkout_data' - url_expected = '/k-fet/k-psul/checkout_data' - - http_methods = ['POST'] - - auth_user = 'team' - auth_forbidden = [None, 'user'] - - def setUp(self): - super().setUp() - self.checkout = Checkout.objects.create( - name='Checkout', - balance=Decimal('10'), - created_by=self.accounts['team'], - valid_from=self.now, - valid_to=self.now + timedelta(days=5), - ) - - def test_ok(self): - r = self.client.post(self.url, {'pk': self.checkout.pk}) - self.assertEqual(r.status_code, 200) - - content = json.loads(r.content.decode('utf-8')) - - expected = { - 'name': 'Checkout', - 'balance': '10.00', - } - - self.assertDictContainsSubset(expected, content) - - self.assertSetEqual(set(content.keys()), set([ - 'balance', 'id', 'name', 'valid_from', 'valid_to', - 'last_statement_at', 'last_statement_balance', - 'last_statement_by_first_name', 'last_statement_by_last_name', - 'last_statement_by_trigramme', - ])) - - class KPsulPerformOperationsViewTests(ViewTestCaseMixin, TestCase): url_name = 'kfet.kpsul.perform_operations' url_expected = '/k-fet/k-psul/perform_operations' @@ -1465,11 +1480,82 @@ class KPsulCancelOperationsViewTests(ViewTestCaseMixin, TestCase): http_methods = ['POST'] - auth_user = 'team' + auth_user = 'team1' auth_forbidden = [None, 'user'] + def get_users_extra(self): + return { + 'team1': create_team('team1', '101', perms=[ + 'kfet.perform_negative_operations', + ]), + 'u1': create_user('user1', '001'), + 'u2': create_user('user2', '002'), + 'u3': create_user('user3', '003'), + } + + def setUp(self): + super().setUp() + + trg1 = TransferGroup.objects.create() + self.trg1_1 = trg1.transfers.create( + from_acc=self.accounts['u1'], + to_acc=self.accounts['u2'], + amount='3.5', + ) + self.trg1_2 = trg1.transfers.create( + from_acc=self.accounts['u2'], + to_acc=self.accounts['u3'], + amount='2.4', + ) + + trg2 = TransferGroup.objects.create( + at=( + timezone.now() - + (kfet_config.cancel_duration + timedelta(seconds=1)) + ), + ) + self.trg2_1 = trg2.transfers.create( + from_acc=self.accounts['u1'], + to_acc=self.accounts['u2'], + amount='5', + ) + def test_ok(self): - pass + data = { + 'transfers[]': [str(self.trg1_1.pk), str(self.trg1_2.pk)], + } + + r = self.client.post(self.url, data) + + self.assertEqual(r.status_code, 200) + + u1 = self.accounts['u1'] + u1.refresh_from_db() + self.assertEqual(u1.balance, Decimal('3.5')) + + u2 = self.accounts['u2'] + u2.refresh_from_db() + self.assertEqual(u2.balance, Decimal('-1.1')) + + u3 = self.accounts['u3'] + u3.refresh_from_db() + self.assertEqual(u3.balance, Decimal('-2.4')) + + def test_error_tooold(self): + data = { + 'transfers[]': [str(self.trg2_1.pk)], + } + + r = self.client.post(self.url, data) + + self.assertEqual(r.status_code, 403) + self.assertDictEqual(json.loads(r.content.decode('utf-8')), { + 'canceled': {}, + 'warnings': {}, + 'errors': { + 'missing_perms': ['Annuler des commandes non récentes'], + }, + }) class KPsulArticlesData(ViewTestCaseMixin, TestCase): @@ -1481,16 +1567,10 @@ class KPsulArticlesData(ViewTestCaseMixin, TestCase): def setUp(self): super().setUp() - category = ArticleCategory.objects.create(name='Catégorie') - self.article1 = Article.objects.create( - category=category, - name='Article 1', - ) - self.article2 = Article.objects.create( - category=category, - name='Article 2', - price=Decimal('2.5'), - ) + self.ac = ArticleCategory.objects.create(name='Catégorie') + + self.a1 = self.ac.articles.create(name='Article 1') + self.a2 = self.ac.articles.create(name='Article 2', price='2.5') def test_ok(self): r = self.client.get(self.url) @@ -1498,24 +1578,35 @@ class KPsulArticlesData(ViewTestCaseMixin, TestCase): content = json.loads(r.content.decode('utf-8')) - articles = content['articles'] - - expected_list = [{ - 'category__name': 'Catégorie', - 'name': 'Article 1', - 'price': '0.00', - }, { - 'category__name': 'Catégorie', - 'name': 'Article 2', - 'price': '2.50', - }] - - for expected, article in zip(expected_list, articles): - self.assertDictContainsSubset(expected, article) - self.assertSetEqual(set(article.keys()), set([ - 'id', 'name', 'price', 'stock', - 'category_id', 'category__name', 'category__has_addcost', - ])) + self.assertEqual(content, { + 'objects': { + 'article': [ + { + 'id': self.a1.pk, + 'name': 'Article 1', + 'price': '0.00', + 'stock': 0, + 'category__id': self.a1.category.pk, + }, + { + 'id': self.a2.pk, + 'name': 'Article 2', + 'price': '2.50', + 'stock': 0, + 'category__id': self.a2.category.pk, + }, + ], + }, + 'related': { + 'category': [ + { + 'id': self.ac.pk, + 'name': 'Catégorie', + 'has_addcost': True, + }, + ], + }, + }) class KPsulUpdateAddcost(ViewTestCaseMixin, TestCase): @@ -1581,34 +1672,6 @@ class HistoryJSONViewTests(ViewTestCaseMixin, TestCase): self.assertEqual(r.status_code, 200) -class AccountReadJSONViewTests(ViewTestCaseMixin, TestCase): - url_name = 'kfet.account.read.json' - url_expected = '/k-fet/accounts/read.json' - - http_methods = ['POST'] - - auth_user = 'team' - auth_forbidden = [None, 'user'] - - def test_ok(self): - r = self.client.post(self.url, {'trigramme': '000'}) - self.assertEqual(r.status_code, 200) - - content = json.loads(r.content.decode('utf-8')) - - expected = { - 'name': 'first last', - 'trigramme': '000', - 'balance': '0.00', - } - self.assertDictContainsSubset(expected, content) - - self.assertSetEqual(set(content.keys()), set([ - 'balance', 'departement', 'email', 'id', 'is_cof', 'is_frozen', - 'name', 'nickname', 'promo', 'trigramme', - ])) - - class SettingsListViewTests(ViewTestCaseMixin, TestCase): url_name = 'kfet.settings' url_expected = '/k-fet/settings/' @@ -1761,62 +1824,6 @@ class TransferPerformViewTests(ViewTestCaseMixin, TestCase): self.assertEqual(team1.balance, Decimal('2.4')) -class TransferCancelViewTests(ViewTestCaseMixin, TestCase): - url_name = 'kfet.transfers.cancel' - url_expected = '/k-fet/transfers/cancel' - - http_methods = ['POST'] - - auth_user = 'team1' - auth_forbidden = [None, 'user', 'team'] - - def get_users_extra(self): - return { - 'team1': create_team('team1', '101', perms=[ - # Convenience - 'kfet.perform_negative_operations', - ]), - } - - @property - def post_data(self): - return { - 'transfers[]': [self.transfer1.pk, self.transfer2.pk], - } - - def setUp(self): - super().setUp() - group = TransferGroup.objects.create() - self.transfer1 = Transfer.objects.create( - group=group, - from_acc=self.accounts['user'], - to_acc=self.accounts['team'], - amount='3.5', - ) - self.transfer2 = Transfer.objects.create( - group=group, - from_acc=self.accounts['team'], - to_acc=self.accounts['root'], - amount='2.4', - ) - - def test_ok(self): - r = self.client.post(self.url, self.post_data) - self.assertEqual(r.status_code, 200) - - user = self.accounts['user'] - user.refresh_from_db() - self.assertEqual(user.balance, Decimal('3.5')) - - team = self.accounts['team'] - team.refresh_from_db() - self.assertEqual(team.balance, Decimal('-1.1')) - - root = self.accounts['root'] - root.refresh_from_db() - self.assertEqual(root.balance, Decimal('-2.4')) - - class InventoryListViewTests(ViewTestCaseMixin, TestCase): url_name = 'kfet.inventory' url_expected = '/k-fet/inventaires/' diff --git a/kfet/views.py b/kfet/views.py index 2280bc48..622d4372 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -1422,7 +1422,7 @@ def history_json(request): # Un non-membre de l'équipe n'a que accès à son historique if not request.user.has_perm('kfet.is_team'): - accounts = [request.user.profile.account] + accounts = [request.user.profile.account_kfet] # Construction de la requête (sur les opérations) pour le prefetch ope_queryset_prefetch = Operation.objects.select_related( @@ -1435,8 +1435,8 @@ def history_json(request): if accounts: transfer_queryset_prefetch = transfer_queryset_prefetch.filter( - Q(from_acc__id__in=accounts) | - Q(to_acc__id__in=accounts)) + Q(from_acc__in=accounts) | + Q(to_acc__in=accounts)) if not request.user.has_perm('kfet.is_team'): acc = request.user.profile.account_kfet @@ -1478,7 +1478,7 @@ def history_json(request): if opes_only: transfergroups = TransferGroup.objects.none() if accounts: - opegroups = opegroups.filter(on_acc_id__in=accounts) + opegroups = opegroups.filter(on_acc__in=accounts) # Construction de la réponse related_data = defaultdict(list) @@ -1568,38 +1568,29 @@ def history_json(request): @teamkfet_required def kpsul_articles_data(request): - articles = ( - Article.objects - .filter(is_sold=True) - .select_related('category')) - articlelist = [] - categorylist = [] + data = {'objects': {}, 'related': {}} - # TODO: nice queryset, no duplicate categories - for article in articles: - articlelist.append({ + data['objects']['article'] = [ + { 'id': article.id, 'name': article.name, 'price': article.price, 'stock': article.stock, - 'category__id': article.category.id, - }) - categorylist.append({ - 'id': article.category.id, - 'name': article.category.name, - 'has_addcost': article.category.has_addcost, - }) - - data = { - 'objects': { - 'article': articlelist, - }, - 'related': { - 'category': categorylist + 'category__id': article.category_id, } - } - return JsonResponse(data) + for article in Article.objects.filter(is_sold=True) + ] + data['related']['category'] = [ + { + 'id': category.id, + 'name': category.name, + 'has_addcost': category.has_addcost, + } + for category in ArticleCategory.objects.all() + ] + + return JsonResponse(data) @teamkfet_required