From fd71aef296cfdf50e9ec672056c525c3bd9752b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 21 Jan 2022 09:36:51 +0100
Subject: [PATCH] wcs: fix card cell reverse relations (#60891)

---
 combo/apps/wcs/models.py |  3 ++
 tests/test_wcs.py        | 79 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py
index c259b0b4..b9cd2c46 100644
--- a/combo/apps/wcs/models.py
+++ b/combo/apps/wcs/models.py
@@ -1081,6 +1081,9 @@ class WcsCardInfosCell(CardMixin, CellBase):
         def get_relation(relations, varname, reverse):
             for relation in relations:
                 if relation['reverse'] == reverse and relation['varname'] == varname:
+                    if reverse and relation['obj'][8:] != self.card_slug:
+                        # if reverse, it's the last part; check it's the correct card model
+                        continue
                     return relation
 
         def follow_data(card_data, relations, varname, parts):
diff --git a/tests/test_wcs.py b/tests/test_wcs.py
index 39c3184a..d5dc2bcd 100644
--- a/tests/test_wcs.py
+++ b/tests/test_wcs.py
@@ -218,6 +218,16 @@ WCS_CARDS_DATA = {
             'fields': {},
         },
     ],
+    'card_f': [
+        {'id': 41, 'fields': {'cardh_raw': 42}},
+    ],
+    'card_g': [
+        {'id': 43, 'fields': {'cardh_raw': 44}},
+    ],
+    'card_h': [
+        {'id': 42, 'fields': {}},
+        {'id': 44, 'fields': {}},
+    ],
 }
 
 WCS_CARDS_CUSTOM_VIEW_DATA = [
@@ -329,6 +339,32 @@ WCS_CARDDEF_SCHEMAS = {
             {'obj': 'carddef:card_d', 'varname': 'carde-foo', 'type': 'item', 'reverse': True},
         ],
     },
+    'card_f': {
+        'name': 'Card F',
+        'fields': [
+            {'label': 'Card H', 'varname': 'cardh', 'type': 'item'},
+        ],
+        'relations': [
+            {'obj': 'carddef:card_h', 'varname': 'cardh', 'type': 'item', 'reverse': False},
+        ],
+    },
+    'card_g': {
+        'name': 'Card G',
+        'fields': [
+            {'label': 'Card H', 'varname': 'cardh', 'type': 'item'},
+        ],
+        'relations': [
+            {'obj': 'carddef:card_h', 'varname': 'cardh', 'type': 'item', 'reverse': False},
+        ],
+    },
+    'card_h': {
+        'name': 'Card H',
+        'fields': [],
+        'relations': [
+            {'obj': 'carddef:card_f', 'varname': 'cardh', 'type': 'item', 'reverse': True},
+            {'obj': 'carddef:card_g', 'varname': 'cardh', 'type': 'item', 'reverse': True},
+        ],
+    },
 }
 
 
@@ -3018,7 +3054,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app):
 
     def multiple(urls):
         resp = app.get(page.get_online_url())
-        assert len(resp.context['cells']) >= 3
+        assert len(resp.context['cells']) >= 2
         assert resp.context['cells'][0].pk == cell.pk
         extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
         for i in range(0, len(resp.context['cells']) - 1):
@@ -3366,6 +3402,47 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app):
         ]
     )
 
+    # reverse relation with many models using the same varname
+    cell.carddef_reference = 'default:card_h'
+    cell.slug = 'slugh'
+    cell.card_ids = '42'
+    cell.related_card_path = ''
+    cell.save()
+    cell2.carddef_reference = 'default:card_f'
+    cell2.slug = 'slugf'
+    cell2.card_ids = ''
+    cell2.related_card_path = 'slugh/reverse:cardh'
+    cell2.save()
+    multiple(
+        urls=[
+            # get first cell data
+            '/api/cards/card_h/42/',
+            # get list of card_f with cardf=42
+            '/api/cards/card_f/list?orig=combo&filter-cardh=42',
+            # and follow cardf reverse relation
+            ['/api/cards/card_f/41/'],
+        ]
+    )
+
+    cell.card_ids = '44'
+    cell.related_card_path = ''
+    cell.save()
+    cell2.carddef_reference = 'default:card_g'
+    cell2.slug = 'slugg'
+    cell2.card_ids = ''
+    cell2.related_card_path = 'slugh/reverse:cardh'
+    cell2.save()
+    multiple(
+        urls=[
+            # get first cell data
+            '/api/cards/card_h/44/',
+            # get list of card_g with cardf=44
+            '/api/cards/card_g/list?orig=combo&filter-cardh=44',
+            # and follow cardf reverse relation
+            ['/api/cards/card_g/43/'],
+        ]
+    )
+
 
 @mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
 def test_card_cell_render_user(mock_send, context, nocache):
-- 
2.34.1

