From 704a70dab13cc3973ec513306a7c3633f93a9455 Mon Sep 17 00:00:00 2001
From: Lukas Holecek <lholecek@redhat.com>
Date: May 25 2018 11:51:49 +0000
Subject: Obsolete waivers only if product version and username is same


Fixes #137

---

diff --git a/tests/test_api_v10.py b/tests/test_api_v10.py
index 7291682..eb8441a 100644
--- a/tests/test_api_v10.py
+++ b/tests/test_api_v10.py
@@ -287,6 +287,36 @@ def test_get_obsolete_waivers(client, session):
     assert res_data['data'][1]['id'] == old_waiver.id
 
 
+def test_obsolete_waivers_with_different_product_version(client, session):
+    old_waiver = create_waiver(session, subject={'subject.test': 'subject'},
+                               testcase='testcase1', username='foo',
+                               product_version='foo-1')
+    new_waiver = create_waiver(session, subject={'subject.test': 'subject'},
+                               testcase='testcase1', username='foo',
+                               product_version='foo-2')
+    r = client.get('/api/v1.0/waivers/?include_obsolete=0')
+    res_data = json.loads(r.get_data(as_text=True))
+    assert r.status_code == 200
+    assert len(res_data['data']) == 2
+    assert res_data['data'][0]['id'] == new_waiver.id
+    assert res_data['data'][1]['id'] == old_waiver.id
+
+
+def test_obsolete_waivers_with_different_username(client, session):
+    old_waiver = create_waiver(session, subject={'subject.test': 'subject'},
+                               testcase='testcase1', username='foo',
+                               product_version='foo-1')
+    new_waiver = create_waiver(session, subject={'subject.test': 'subject'},
+                               testcase='testcase1', username='bar',
+                               product_version='foo-1')
+    r = client.get('/api/v1.0/waivers/?include_obsolete=0')
+    res_data = json.loads(r.get_data(as_text=True))
+    assert r.status_code == 200
+    assert len(res_data['data']) == 2
+    assert res_data['data'][0]['id'] == new_waiver.id
+    assert res_data['data'][1]['id'] == old_waiver.id
+
+
 def test_filtering_waivers_by_subject(client, session):
     create_waiver(session, subject={'subject.test1': 'subject1'},
                   testcase='testcase', username='foo-1', product_version='foo-1')
diff --git a/waiverdb/api_v1.py b/waiverdb/api_v1.py
index a62ab3a..745679f 100644
--- a/waiverdb/api_v1.py
+++ b/waiverdb/api_v1.py
@@ -85,6 +85,22 @@ def reqparse_since(since):
     return start, end
 
 
+def _filter_out_obsolete_waivers(query):
+    """
+    Filters out obsolete waivers.
+
+    A waiver is obsolete if there exist another one that is more recent with
+    same subject, test case name, username and product_version.
+    """
+    subquery = db.session.query(func.max(Waiver.id)).group_by(
+        cast(Waiver.subject, db.Text),
+        Waiver.testcase,
+        Waiver.username,
+        Waiver.product_version,
+    )
+    return query.filter(Waiver.id.in_(subquery))
+
+
 # RP contains request parsers (reqparse.RequestParser).
 #    Parsers are added in each 'resource section' for better readability
 RP = {}
@@ -193,9 +209,8 @@ class WaiversResource(Resource):
             if since_end:
                 query = query.filter(Waiver.timestamp <= since_end)
         if not args['include_obsolete']:
-            subquery = db.session.query(func.max(Waiver.id)).group_by(cast(Waiver.subject, db.Text),
-                                                                      Waiver.testcase)
-            query = query.filter(Waiver.id.in_(subquery))
+            query = _filter_out_obsolete_waivers(query)
+
         query = query.order_by(Waiver.timestamp.desc())
         return json_collection(query, args['page'], args['limit'])
 
@@ -467,9 +482,7 @@ class GetWaiversBySubjectsAndTestcases(Resource):
             if since_end:
                 query = query.filter(Waiver.timestamp <= since_end)
         if not data.get('include_obsolete', False):
-            subquery = db.session.query(func.max(Waiver.id)).group_by(cast(Waiver.subject, db.Text),
-                                                                      Waiver.testcase)
-            query = query.filter(Waiver.id.in_(subquery))
+            query = _filter_out_obsolete_waivers(query)
 
         query = query.order_by(Waiver.timestamp.desc())
         return {'data': marshal(query.all(), waiver_fields)}

