--- a/hgext/reviewboard/tests/test-commits-added.t
+++ b/hgext/reviewboard/tests/test-commits-added.t
@@ -95,16 +95,17 @@ The parent review request should be upda
extra_data: {}
commit_extra_data:
p2rb: true
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[2, 3, 4]'
+ flags: []
diffs: []
approved: false
approval_failure: The review request is not public.
draft:
bugs:
- '1'
commit: bz://1/mynick
summary: bz://1/mynick
--- a/hgext/reviewboard/tests/test-commits-deleted-no-obsolescence.t
+++ b/hgext/reviewboard/tests/test-commits-deleted-no-obsolescence.t
@@ -129,16 +129,17 @@ Review request 6 should be added to the
p2rb.commits: '[["0b3e14fe3ff19019110705e72dcf563c0ef551f6", 2], ["bce658a3f6d6aa04bf5c449e0e779e839de4690e",
3], ["713878e22d952d478e88bfdef897fdfc73060351", 4], ["4d0f846364eb509a1b6ae3294f05439101f6e7d3",
5], ["4e50148c492dde95397cd666f2d4e4ad4fd2176f", 6]]'
p2rb.discard_on_publish_rids: '[6]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -250,16 +251,17 @@ Review 6 should be marked as discarded
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4e50148c492dde95397cd666f2d4e4ad4fd2176f
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 6
revision: 1
base_commit_id: 4d0f846364eb509a1b6ae3294f05439101f6e7d3
name: diff
extra: {}
patch:
- diff --git a/foo5 b/foo5
@@ -325,16 +327,17 @@ The review request corresponding to the
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 0b3e14fe3ff19019110705e72dcf563c0ef551f6
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -369,16 +372,17 @@ Review request 2 should be marked as dis
p2rb.commits: '[["0b3e14fe3ff19019110705e72dcf563c0ef551f6", 2], ["bce658a3f6d6aa04bf5c449e0e779e839de4690e",
3], ["713878e22d952d478e88bfdef897fdfc73060351", 4], ["4d0f846364eb509a1b6ae3294f05439101f6e7d3",
5]]'
p2rb.discard_on_publish_rids: '[2]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -547,16 +551,17 @@ The parent review should have been updat
p2rb.base_commit: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.commits: '[["eeb6d49dcb0950d771959358f662cf2e5ddc9dc1", 3], ["607f375f35c0866a8e08bc1d6aaecc6ad259ed6e",
4], ["81ee86efd38ff60717aeeeff153292e84e58be0b", 5]]'
p2rb.discard_on_publish_rids: '[4]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -741,16 +746,17 @@ recycling behavior when commit IDs are p
p2rb.base_commit: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.commits: '[["eeb6d49dcb0950d771959358f662cf2e5ddc9dc1", 3], ["607f375f35c0866a8e08bc1d6aaecc6ad259ed6e",
4], ["81ee86efd38ff60717aeeeff153292e84e58be0b", 5]]'
p2rb.discard_on_publish_rids: '[5]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
--- a/hgext/reviewboard/tests/test-commits-deleted-obsolescence.t
+++ b/hgext/reviewboard/tests/test-commits-deleted-obsolescence.t
@@ -135,16 +135,17 @@ on publish.
p2rb.commits: '[["0b3e14fe3ff19019110705e72dcf563c0ef551f6", 2], ["bce658a3f6d6aa04bf5c449e0e779e839de4690e",
3], ["713878e22d952d478e88bfdef897fdfc73060351", 4], ["4d0f846364eb509a1b6ae3294f05439101f6e7d3",
5], ["4e50148c492dde95397cd666f2d4e4ad4fd2176f", 6]]'
p2rb.discard_on_publish_rids: '[6]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -258,16 +259,17 @@ The parent review should have dropped th
p2rb.commits: '[["0b3e14fe3ff19019110705e72dcf563c0ef551f6", 2], ["bce658a3f6d6aa04bf5c449e0e779e839de4690e",
3], ["713878e22d952d478e88bfdef897fdfc73060351", 4], ["4d0f846364eb509a1b6ae3294f05439101f6e7d3",
5]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -355,16 +357,17 @@ Review 6 should be marked as discarded
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4e50148c492dde95397cd666f2d4e4ad4fd2176f
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 6
revision: 1
base_commit_id: 4d0f846364eb509a1b6ae3294f05439101f6e7d3
name: diff
extra: {}
patch:
- diff --git a/foo5 b/foo5
@@ -432,16 +435,17 @@ on publish.
p2rb.commits: '[["0b3e14fe3ff19019110705e72dcf563c0ef551f6", 2], ["bce658a3f6d6aa04bf5c449e0e779e839de4690e",
3], ["713878e22d952d478e88bfdef897fdfc73060351", 4], ["4d0f846364eb509a1b6ae3294f05439101f6e7d3",
5]]'
p2rb.discard_on_publish_rids: '[2]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -577,16 +581,17 @@ The dropped commit should now be discard
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 0b3e14fe3ff19019110705e72dcf563c0ef551f6
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -649,16 +654,17 @@ The parent review should have been updat
p2rb.base_commit: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.commits: '[["eeb6d49dcb0950d771959358f662cf2e5ddc9dc1", 3], ["a27a94c54524d4331dec2f92f647067bfd6dfbd4",
5]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -820,16 +826,17 @@ because the new commit is logically diff
p2rb.base_commit: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.commits: '[["eeb6d49dcb0950d771959358f662cf2e5ddc9dc1", 3], ["a27a94c54524d4331dec2f92f647067bfd6dfbd4",
5]]'
p2rb.discard_on_publish_rids: '[5]'
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[7]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
name: diff
extra: {}
patch:
- diff --git a/foo1 b/foo1
@@ -1001,16 +1008,17 @@ Review request 5 (whose commit was delet
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: a27a94c54524d4331dec2f92f647067bfd6dfbd4
p2rb.first_public_ancestor: 93d9429b41ecf0d2ad8c62b6ea26686dd20330f4
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 5
revision: 1
base_commit_id: 713878e22d952d478e88bfdef897fdfc73060351
name: diff
extra: {}
patch:
- diff --git a/foo4 b/foo4
@@ -1059,16 +1067,17 @@ Review request 5 (whose commit was delet
summary: ''
description: ''
target_people: []
extra_data: {}
commit_extra_data:
p2rb: true
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs: []
approved: false
approval_failure: The review request is not public.
draft:
bugs:
- '1'
commit: null
summary: Bug 1 - Foo 6
--- a/hgext/reviewboard/tests/test-operation-prevention.t
+++ b/hgext/reviewboard/tests/test-operation-prevention.t
@@ -50,16 +50,17 @@ Publishing the parent should succeed.
p2rb: true
p2rb.base_commit: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.commits: '[["4f4c73d9c6594a0a800a82758ceb6fb12a6b9f83", 2]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -90,16 +91,17 @@ Publishing the parent should succeed.
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4f4c73d9c6594a0a800a82758ceb6fb12a6b9f83
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
--- a/hgext/reviewboard/tests/test-push-http.t
+++ b/hgext/reviewboard/tests/test-push-http.t
@@ -375,16 +375,17 @@ Test creating a review via HTTP
p2rb.base_commit: 8d7f5c4152d8f67d67500d3b92903e365c0122f1
p2rb.commits: '[["9d326020e0dcd3e421680e4b78bf80c9e30df0e6", 2], ["c6548fe145857055779b23d94ef3f911e8d261b0",
3]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 8d7f5c4152d8f67d67500d3b92903e365c0122f1
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 8d7f5c4152d8f67d67500d3b92903e365c0122f1
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
--- a/hgext/reviewboard/tests/test-review-request-approval.t
+++ b/hgext/reviewboard/tests/test-review-request-approval.t
@@ -60,16 +60,37 @@ Create a review request from an L1 user
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4f4c73d9c6594a0a800a82758ceb6fb12a6b9f83
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: '?'
+ review_request: 2
+ setter: level1a
+ requestee: level3
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: '?'
+ review_request: 2
+ setter: level1a
+ requestee: level1b
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -107,16 +128,37 @@ Have an L1 user provide a r+ review whic
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4f4c73d9c6594a0a800a82758ceb6fb12a6b9f83
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: '?'
+ review_request: 2
+ setter: level1a
+ requestee: level3
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: +
+ review_request: 2
+ setter: level1b
+ requestee: level1b
+ review: 1
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -164,16 +206,37 @@ Have an L3 user provide a r+ review whic
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4f4c73d9c6594a0a800a82758ceb6fb12a6b9f83
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: +
+ review_request: 2
+ setter: level3
+ requestee: level3
+ review: 2
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: +
+ review_request: 2
+ setter: level1b
+ requestee: level1b
+ review: 1
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -227,16 +290,37 @@ Posting a new review without r+ should c
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4f4c73d9c6594a0a800a82758ceb6fb12a6b9f83
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: '-'
+ review_request: 2
+ setter: level3
+ requestee: level3
+ review: 3
+ review_extra_data_flag: r-
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: +
+ review_request: 2
+ setter: level1b
+ requestee: level1b
+ review: 1
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -299,16 +383,37 @@ One more r+ should switch it back to app
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 4f4c73d9c6594a0a800a82758ceb6fb12a6b9f83
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: +
+ review_request: 2
+ setter: level3
+ requestee: level3
+ review: 4
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: +
+ review_request: 2
+ setter: level1b
+ requestee: level1b
+ review: 1
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -381,16 +486,37 @@ Even though the author is L1, adding a n
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: f867b363f9fd58135c77672e3c34f222f16ff677
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: '?'
+ review_request: 2
+ setter: level1a
+ requestee: level3
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: '?'
+ review_request: 2
+ setter: level1a
+ requestee: level1b
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -474,16 +600,37 @@ A new r+ from L3 should give approval
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: f867b363f9fd58135c77672e3c34f222f16ff677
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: +
+ review_request: 2
+ setter: level3
+ requestee: level3
+ review: 5
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: '?'
+ review_request: 2
+ setter: level1a
+ requestee: level1b
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -580,16 +727,37 @@ Opening issues, even from an L1 user, sh
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: f867b363f9fd58135c77672e3c34f222f16ff677
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: +
+ review_request: 2
+ setter: level3
+ requestee: level3
+ review: 5
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: '-'
+ review_request: 2
+ setter: level1b
+ requestee: level1b
+ review: 6
+ review_extra_data_flag: r-
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -701,16 +869,37 @@ Fixing the issue should restore approval
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: f867b363f9fd58135c77672e3c34f222f16ff677
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 1
+ type: review
+ value: +
+ review_request: 2
+ setter: level3
+ requestee: level3
+ review: 5
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 2
+ type: review
+ value: '-'
+ review_request: 2
+ setter: level1b
+ requestee: level1b
+ review: 6
+ review_extra_data_flag: r-
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -830,16 +1019,37 @@ Review requests created by L3 users
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: b366ef9913208b4030857319aa20520f229a74f3
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://2/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 3
+ type: review
+ value: '?'
+ review_request: 4
+ setter: level3
+ requestee: level1a
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 4
+ type: review
+ value: '?'
+ review_request: 4
+ setter: level3
+ requestee: level1b
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 6
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -877,16 +1087,37 @@ Even a ship-it from an L1 user will give
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: b366ef9913208b4030857319aa20520f229a74f3
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://2/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 3
+ type: review
+ value: +
+ review_request: 4
+ setter: level1a
+ requestee: level1a
+ review: 7
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 4
+ type: review
+ value: '?'
+ review_request: 4
+ setter: level3
+ requestee: level1b
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 6
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -937,16 +1168,37 @@ ship-its. Posting a new diff should not
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: bedcf57f515ad540f582962e37ecd424d82424fd
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://2/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 3
+ type: review
+ value: '?'
+ review_request: 4
+ setter: level3
+ requestee: level1a
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 4
+ type: review
+ value: '?'
+ review_request: 4
+ setter: level3
+ requestee: level1b
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 6
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
--- a/hgext/reviewboard/tests/test-review-request-closed-discarded.t
+++ b/hgext/reviewboard/tests/test-review-request-closed-discarded.t
@@ -133,16 +133,17 @@ no Commit ID set.
p2rb.base_commit: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.commits: '[["98467d80785ec84dd871f213c167ed704a6d974d", 2], ["3a446ae4382006c43cdfa5aa33c494f582736f35",
3]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -175,16 +176,17 @@ Child review request with ID 2 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -217,16 +219,17 @@ Child review request with ID 3 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 3a446ae4382006c43cdfa5aa33c494f582736f35
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 3
revision: 1
base_commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -326,16 +329,17 @@ Commit ID re-instated.
p2rb.base_commit: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.commits: '[["98467d80785ec84dd871f213c167ed704a6d974d", 2], ["3a446ae4382006c43cdfa5aa33c494f582736f35",
3]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -389,16 +393,17 @@ Child review request with ID 2 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -451,16 +456,17 @@ Child review request with ID 3 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 3a446ae4382006c43cdfa5aa33c494f582736f35
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 3
revision: 1
base_commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -579,16 +585,17 @@ Squashed review request should be publis
p2rb.base_commit: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.commits: '[["98467d80785ec84dd871f213c167ed704a6d974d", 2], ["3a446ae4382006c43cdfa5aa33c494f582736f35",
3]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -621,16 +628,17 @@ Child review request with ID 2 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -663,16 +671,17 @@ Child review request with ID 3 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 3a446ae4382006c43cdfa5aa33c494f582736f35
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 3
revision: 1
base_commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -800,16 +809,17 @@ Pushing to a discarded review series wil
p2rb.base_commit: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.commits: '[["98467d80785ec84dd871f213c167ed704a6d974d", 2], ["3a446ae4382006c43cdfa5aa33c494f582736f35",
3]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -841,16 +851,17 @@ Pushing to a discarded review series wil
p2rb.base_commit: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.commits: '[["98467d80785ec84dd871f213c167ed704a6d974d", 5], ["3a446ae4382006c43cdfa5aa33c494f582736f35",
6], ["1ec9946fd47ff9b5cb07e9d9c8b4d393b688e01b", 7]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 4
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
--- a/hgext/reviewboard/tests/test-review-request-closed-submitted.t
+++ b/hgext/reviewboard/tests/test-review-request-closed-submitted.t
@@ -75,16 +75,17 @@ Squashed review request with ID 1 should
p2rb.base_commit: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.commits: '[["98467d80785ec84dd871f213c167ed704a6d974d", 2], ["3a446ae4382006c43cdfa5aa33c494f582736f35",
3]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -117,16 +118,17 @@ Child review request with ID 2 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -157,16 +159,17 @@ Child review request with ID 2 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 3a446ae4382006c43cdfa5aa33c494f582736f35
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 3
revision: 1
base_commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -224,16 +227,17 @@ Squashed review request with ID 1 should
p2rb.base_commit: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.commits: '[["98467d80785ec84dd871f213c167ed704a6d974d", 2], ["3a446ae4382006c43cdfa5aa33c494f582736f35",
3]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -266,16 +270,17 @@ Child review request with ID 2 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 7c5bdf0cec4a90edb36300f8f3679857f46db829
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -308,16 +313,17 @@ Child review request with ID 3 should be
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 3a446ae4382006c43cdfa5aa33c494f582736f35
p2rb.first_public_ancestor: 7c5bdf0cec4a90edb36300f8f3679857f46db829
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 3
revision: 1
base_commit_id: 98467d80785ec84dd871f213c167ed704a6d974d
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
--- a/hgext/reviewboard/tests/test-review-request-delegation.t
+++ b/hgext/reviewboard/tests/test-review-request-delegation.t
@@ -380,8 +380,13 @@ Test ensure-drafts
- reviewer1
reviewers_status:
reviewer1:
review_flag: r?
ship_it: false
diff:
delete: 0
insert: 1
+
+Cleanup
+
+ $ mozreview stop
+ stopped 9 containers
--- a/hgext/reviewboard/tests/test-review-request-delete-draft.t
+++ b/hgext/reviewboard/tests/test-review-request-delete-draft.t
@@ -84,16 +84,17 @@ We should have a disagreement between pu
p2rb: true
p2rb.base_commit: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.commits: '[["65e5c536f9cc5816ef28ebaff6a0db47b9af0fee", 2]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -157,16 +158,17 @@ We should have a disagreement between pu
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 65e5c536f9cc5816ef28ebaff6a0db47b9af0fee
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -235,16 +237,17 @@ Discarding the parent review request dra
p2rb: true
p2rb.base_commit: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.commits: '[["65e5c536f9cc5816ef28ebaff6a0db47b9af0fee", 2]]'
p2rb.discard_on_publish_rids: '[]'
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: true
p2rb.unpublished_rids: '[]'
+ flags: []
diffs:
- id: 1
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -275,16 +278,17 @@ Discarding the parent review request dra
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 65e5c536f9cc5816ef28ebaff6a0db47b9af0fee
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
new file mode 100644
--- /dev/null
+++ b/hgext/reviewboard/tests/test-reviewer-flags-in-db.t
@@ -0,0 +1,569 @@
+#require mozreviewdocker
+
+ $ . $TESTDIR/hgext/reviewboard/tests/helpers.sh
+ $ commonenv
+
+Enable obsolescence so we can test code paths which use it.
+
+ $ cat >> client/.hg/hgrc << EOF
+ > [experimental]
+ > evolution = all
+ > EOF
+
+Create an initial commit.
+
+ $ cd client
+ $ echo foo > foo
+ $ hg commit -A -m 'root commit'
+ adding foo
+ $ hg phase --public -r .
+
+Add some potential reviewers.
+
+ $ mozreview create-user romulus@example.com password 'Romulus :romulus'
+ Created user 6
+ $ mozreview create-user remus@example.com password 'Remus :remus'
+ Created user 7
+
+We create a user who has decided to capitalize their ircnick.
+
+ $ mozreview create-user ryanvm@example.com password 'Ryan :RyanVM'
+ Created user 8
+
+Create few draft review requests
+
+ $ bugzilla create-bug TestProduct TestComponent 'First Bug'
+ $ echo initial > foo
+ $ hg commit -m 'Bug 1 - some stuff; r?romulus'
+ $ echo blah >> foo
+ $ hg commit -m 'Bug 1 - More stuff; r?romulus, r?remus'
+
+ $ hg push --config reviewboard.autopublish=false
+ pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
+ (adding commit id to 2 changesets)
+ searching for changes
+ remote: adding changesets
+ remote: adding manifests
+ remote: adding file changes
+ remote: added 3 changesets with 3 changes to 1 files
+ remote: recorded push in pushlog
+ submitting 2 changesets for review
+
+ changeset: 3:7122d7b3a455
+ summary: Bug 1 - some stuff; r?romulus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/2 (draft)
+
+ changeset: 4:1cac575c1bc7
+ summary: Bug 1 - More stuff; r?romulus, r?remus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/3 (draft)
+
+ review id: bz://1/mynick
+ review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/1 (draft)
+ (visit review url to publish these review requests so others can see them)
+
+Flags are not created for draft review requests
+
+ $ hg push
+ pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
+ searching for changes
+ no changes found
+ submitting 2 changesets for review
+
+ changeset: 3:7122d7b3a455
+ summary: Bug 1 - some stuff; r?romulus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/2 (draft)
+
+ changeset: 4:1cac575c1bc7
+ summary: Bug 1 - More stuff; r?romulus, r?remus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/3 (draft)
+
+ review id: bz://1/mynick
+ review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/1 (draft)
+
+ publish these review requests now (Yn)? y
+ (published review request 1)
+ [1]
+
+No Flag should be created for parent review request
+
+ $ reviewboard dumpflags 1
+ review_request_id: 1
+ flags: []
+
+Flags for review requests 2 and 3 are saved on publishing
+
+ $ reviewboard dumpflags 2
+ review_request_id: 2
+ flags:
+ - id: 1
+ type: review
+ value: '?'
+ review_request: 2
+ setter: default+5
+ requestee: romulus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+
+ $ reviewboard dumpflags 3
+ review_request_id: 3
+ flags:
+ - id: 2
+ type: review
+ value: '?'
+ review_request: 3
+ setter: default+5
+ requestee: romulus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 3
+ type: review
+ value: '?'
+ review_request: 3
+ setter: default+5
+ requestee: remus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+
+ $ echo blah >> foo
+ $ hg commit --amend -l - << EOF
+ > Bug 1 - Even more stuff; r?romulus, r?remus
+ >
+ > MozReview-Commit-ID: hE3OiG
+ > EOF
+ $ hg push
+ pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
+ searching for changes
+ remote: adding changesets
+ remote: adding manifests
+ remote: adding file changes
+ remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+ remote: recorded push in pushlog
+ submitting 2 changesets for review
+
+ changeset: 3:7122d7b3a455
+ summary: Bug 1 - some stuff; r?romulus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/2
+
+ changeset: 6:f7778a69cf9c
+ summary: Bug 1 - Even more stuff; r?romulus, r?remus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/3 (draft)
+
+ review id: bz://1/mynick
+ review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/1 (draft)
+
+ publish these review requests now (Yn)? y
+ (published review request 1)
+
+These flags are already created.
+
+ $ reviewboard dumpflags 3
+ review_request_id: 3
+ flags:
+ - id: 2
+ type: review
+ value: '?'
+ review_request: 3
+ setter: default+5
+ requestee: romulus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 3
+ type: review
+ value: '?'
+ review_request: 3
+ setter: default+5
+ requestee: remus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+
+A new flag is created when adding a reviewer
+ $ rbmanage add-reviewer 3 --user admin+1
+ 3 people listed on review request
+ $ hg push
+ pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
+ searching for changes
+ no changes found
+ submitting 2 changesets for review
+
+ changeset: 3:7122d7b3a455
+ summary: Bug 1 - some stuff; r?romulus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/2
+
+ changeset: 6:f7778a69cf9c
+ summary: Bug 1 - Even more stuff; r?romulus, r?remus
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/3 (draft)
+
+ review id: bz://1/mynick
+ review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/1 (draft)
+
+ publish these review requests now (Yn)? y
+ (published review request 1)
+ [1]
+
+ $ reviewboard dumpflags 3
+ review_request_id: 3
+ flags:
+ - id: 2
+ type: review
+ value: '?'
+ review_request: 3
+ setter: default+5
+ requestee: romulus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 3
+ type: review
+ value: '?'
+ review_request: 3
+ setter: default+5
+ requestee: remus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 4
+ type: review
+ value: '?'
+ review_request: 3
+ setter: default+5
+ requestee: admin+1
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+
+Unrecognized reviewers are ignored
+
+ $ hg phase --public -r .
+ $ bugzilla create-bug TestProduct TestComponent 'Second Bug'
+ $ echo blah >> foo
+ $ hg commit -m 'Bug 2 - different stuff; r?cthulhu'
+ $ hg push
+ pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
+ searching for changes
+ remote: adding changesets
+ remote: adding manifests
+ remote: adding file changes
+ remote: added 1 changesets with 1 changes to 1 files
+ remote: recorded push in pushlog
+ submitting 1 changesets for review
+ unrecognized reviewer: cthulhu
+
+ changeset: 7:b5fe24c33ddf
+ summary: Bug 2 - different stuff; r?cthulhu
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/5 (draft)
+
+ review id: bz://2/mynick
+ review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/4 (draft)
+
+ (review requests lack reviewers; visit review url to assign reviewers)
+
+ publish these review requests now (Yn)? y
+ (published review request 4)
+
+ $ reviewboard dumpflags 5
+ review_request_id: 5
+ flags: []
+
+
+Reviewer identification is case insensitive.
+
+ $ echo blah >> foo
+ $ hg commit -m 'Bug 2 - better stuff; r?remus r?ryanvm'
+ $ hg push
+ pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
+ searching for changes
+ remote: adding changesets
+ remote: adding manifests
+ remote: adding file changes
+ remote: added 1 changesets with 1 changes to 1 files
+ remote: recorded push in pushlog
+ submitting 2 changesets for review
+
+ changeset: 7:b5fe24c33ddf
+ summary: Bug 2 - different stuff; r?cthulhu
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/5
+
+ changeset: 8:c8a58a1d5f9f
+ summary: Bug 2 - better stuff; r?remus r?ryanvm
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/6 (draft)
+
+ review id: bz://2/mynick
+ review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/4 (draft)
+
+ (review requests lack reviewers; visit review url to assign reviewers)
+
+ publish these review requests now (Yn)? y
+ (published review request 4)
+
+ $ reviewboard dumpflags 6
+ review_request_id: 6
+ flags:
+ - id: 5
+ type: review
+ value: '?'
+ review_request: 6
+ setter: default+5
+ requestee: remus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 6
+ type: review
+ value: '?'
+ review_request: 6
+ setter: default+5
+ requestee: RyanVM
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+
+Removing reviewer who hasn't created a review is deleting related flags
+
+ $ rbmanage remove-reviewer 6 --user remus
+ 1 people listed on review request
+ $ rbmanage publish 4
+
+ $ rbmanage list-reviewers 6
+ RyanVM
+
+ $ reviewboard dumpflags 6
+ review_request_id: 6
+ flags:
+ - id: 6
+ type: review
+ value: '?'
+ review_request: 6
+ setter: default+5
+ requestee: RyanVM
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+
+Review with r- should update the flag so setter and requestee is the same user
+
+ $ exportbzauth ryanvm@example.com password
+ $ rbmanage create-review 6 --body-top "No way" --public --review-flag='r-'
+ created review 1
+ $ exportbzauth default@example.com password
+ $ reviewboard dumpflags 6
+ review_request_id: 6
+ flags:
+ - id: 6
+ type: review
+ value: '-'
+ review_request: 6
+ setter: RyanVM
+ requestee: RyanVM
+ review: 1
+ review_extra_data_flag: r-
+ change_description: ''
+ timestamp: '*' (glob)
+
+
+Review with r+
+
+ $ exportbzauth ryanvm@example.com password
+ $ rbmanage create-review 6 --body-top "Ship It!" --public --review-flag='r+'
+ created review 2
+ $ exportbzauth default@example.com password
+ $ reviewboard dumpflags 6
+ review_request_id: 6
+ flags:
+ - id: 6
+ type: review
+ value: +
+ review_request: 6
+ setter: RyanVM
+ requestee: RyanVM
+ review: 2
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+
+No flag should be created when an impropmptu review is added with empty status
+
+ $ echo blahblah > foo
+ $ hg commit -m 'Bug 2 - new commit'
+ $ hg push
+ pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
+ searching for changes
+ remote: adding changesets
+ remote: adding manifests
+ remote: adding file changes
+ remote: added 1 changesets with 1 changes to 1 files
+ remote: recorded push in pushlog
+ submitting 3 changesets for review
+
+ changeset: 7:b5fe24c33ddf
+ summary: Bug 2 - different stuff; r?cthulhu
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/5
+
+ changeset: 8:c8a58a1d5f9f
+ summary: Bug 2 - better stuff; r?remus r?ryanvm
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/6
+
+ changeset: 9:96e466dfc0a4
+ summary: Bug 2 - new commit
+ review: http://$DOCKER_HOSTNAME:$HGPORT1/r/7 (draft)
+
+ review id: bz://2/mynick
+ review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/4 (draft)
+
+ (review requests lack reviewers; visit review url to assign reviewers)
+
+ publish these review requests now (Yn)? y
+ (published review request 4)
+ $ mozreview create-user level1@example.com password 'Level 1 User :level1' --uid 2003 --scm-level 1 --bugzilla-group editbugs
+ Created user 9
+ $ rbmanage associate-ldap-user level1 level1@example.com
+ level1@example.com associated with level1
+ $ exportbzauth level1@example.com password
+ $ rbmanage create-review 7 --body-top "Just a comment" --public
+ created review 3
+ $ exportbzauth default@example.com password
+ $ reviewboard dumpflags 7
+ review_request_id: 7
+ flags: []
+ $ reviewboard dumpreview 7
+ id: 7
+ status: pending
+ public: true
+ bugs:
+ - '2'
+ commit: null
+ submitter: default+5
+ summary: Bug 2 - new commit
+ description:
+ - Bug 2 - new commit
+ - ''
+ - 'MozReview-Commit-ID: OTOPw0'
+ target_people: []
+ extra_data:
+ calculated_trophies: true
+ commit_extra_data:
+ p2rb: true
+ p2rb.author: test
+ p2rb.commit_id: 96e466dfc0a48261e5c578decfc8c0408775e935
+ p2rb.first_public_ancestor: f7778a69cf9c89cb483b97a3333a8041d6aac497
+ p2rb.identifier: bz://2/mynick
+ p2rb.is_squashed: false
+ flags: []
+ diffs:
+ - id: 13
+ revision: 1
+ base_commit_id: c8a58a1d5f9f8a17a6892504f2d3b3179954e31a
+ name: diff
+ extra: {}
+ patch:
+ - diff --git a/foo b/foo
+ - '--- a/foo'
+ - +++ b/foo
+ - '@@ -1,5 +1,1 @@'
+ - -initial
+ - -blah
+ - -blah
+ - -blah
+ - -blah
+ - +blahblah
+ - ''
+ approved: false
+ approval_failure: A suitable reviewer has not given a "Ship It!"
+ review_count: 1
+ reviews:
+ - id: 3
+ public: true
+ ship_it: false
+ extra_data:
+ p2rb.review_flag: ''
+ body_top: Just a comment
+ body_top_text_type: plain
+ diff_comments: []
+
+Impromptu review can't have an 'r?' status
+
+ $ exportbzauth level1@example.com password
+ $ rbmanage create-review 7 --body-top "Ship it please" --public --review-flag='r?'
+ created review 4
+ $ exportbzauth default@example.com password
+ $ reviewboard dumpflags 7
+ review_request_id: 7
+ flags: []
+
+A flag should be created if adding an impromptu review with a status
+
+ $ exportbzauth level1@example.com password
+ $ rbmanage create-review 7 --body-top "Ship it please" --public --review-flag='r+'
+ created review 5
+ $ exportbzauth default@example.com password
+ $ reviewboard dumpflags 7
+ review_request_id: 7
+ flags:
+ - id: 7
+ type: review
+ value: +
+ review_request: 7
+ setter: level1
+ requestee: level1
+ review: 5
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+
+Adding a user who created an impromptu review to target_people does not change flags
+
+ $ rbmanage add-reviewer 7 --user level1
+ 1 people listed on review request
+ $ rbmanage publish 4
+ $ reviewboard dumpflags 7
+ review_request_id: 7
+ flags:
+ - id: 7
+ type: review
+ value: +
+ review_request: 7
+ setter: level1
+ requestee: level1
+ review: 5
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+
+Removing a user who had a review with a flag set is only clearing the requestee field
+
+ $ rbmanage remove-reviewer 7 --user level1
+ 0 people listed on review request
+ $ rbmanage publish 4
+ $ reviewboard dumpflags 7
+ review_request_id: 7
+ flags:
+ - id: 7
+ type: review
+ value: +
+ review_request: 7
+ setter: level1
+ requestee: ''
+ review: 5
+ review_extra_data_flag: r+
+ change_description: ''
+ timestamp: '*' (glob)
+
+Cleanup
+
+ $ mozreview stop
+ stopped 9 containers
--- a/hgext/reviewboard/tests/test-reviewer-flags.t
+++ b/hgext/reviewboard/tests/test-reviewer-flags.t
@@ -82,17 +82,16 @@ There are no warnings for reviewers who
review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/1 (draft)
publish these review requests now (Yn)? y
(published review request 1)
$ rbmanage list-reviewers 2
cthulhu
-
There are warnings for reviewers who haved granted a non ship-it review when
using r=.
$ exportbzauth cthulhu@example.com password
$ rbmanage create-review 2 --body-top "No way you should ship-it!" --public --review-flag='r-'
created review 2
$ exportbzauth default@example.com password
--- a/hgext/reviewboard/tests/test-specify-reviewers.t
+++ b/hgext/reviewboard/tests/test-specify-reviewers.t
@@ -227,16 +227,37 @@ Publishing series during push works
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 214fce3608426755a50ae60ae8645eb9bc1f7537
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags:
+ - id: 14
+ type: review
+ value: '?'
+ review_request: 10
+ setter: default+5
+ requestee: romulus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
+ - id: 15
+ type: review
+ value: '?'
+ review_request: 10
+ setter: default+5
+ requestee: remus
+ review: ''
+ review_extra_data_flag: ''
+ change_description: ''
+ timestamp: '*' (glob)
diffs:
- id: 10
revision: 1
base_commit_id: ccfcf9b70a65731d01240f24815edf0cf6b64739
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -549,17 +570,16 @@ Unrecognized reviewers should be ignored
review url: http://$DOCKER_HOSTNAME:$HGPORT1/r/12 (draft)
(review requests lack reviewers; visit review url to assign reviewers)
publish these review requests now (Yn)? y
(published review request 12)
$ rbmanage list-reviewers 12
-
Reviewer identification should be case insensitive.
$ echo blah >> foo
$ hg commit -m 'Bug 2 - better stuff; r?ryanvm'
$ hg push -c 28
pushing to ssh://$DOCKER_HOSTNAME:$HGPORT6/test-repo
searching for changes
remote: adding changesets
@@ -605,13 +625,12 @@ Reviewer deduction can be disabled with
(review requests lack reviewers; visit review url to assign reviewers)
publish these review requests now (Yn)? y
(published review request 12)
$ rbmanage list-reviewers 15
-
Cleanup
$ mozreview stop
stopped 9 containers
--- a/hgext/reviewboard/tests/test-unicode.t
+++ b/hgext/reviewboard/tests/test-unicode.t
@@ -53,16 +53,17 @@ The globbing is patching over a bug in m
calculated_trophies: true
commit_extra_data:
p2rb: true
p2rb.author: test
p2rb.commit_id: 86ab97a5dd61e8ec7ff3c23212db732e3531af01
p2rb.first_public_ancestor: 3a9f6899ef84c99841f546030b036d0124a863cf
p2rb.identifier: bz://1/mynick
p2rb.is_squashed: false
+ flags: []
diffs:
- id: 2
revision: 1
base_commit_id: 3a9f6899ef84c99841f546030b036d0124a863cf
name: diff
extra: {}
patch:
- diff --git a/foo b/foo
@@ -176,16 +177,17 @@ Put some wonky byte sequences in the dif
summary: ''
description: ''
target_people: []
extra_data: {}
commit_extra_data:
p2rb: true
p2rb.identifier: bz://2/mynick
p2rb.is_squashed: false
+ flags: []
diffs: []
approved: false
approval_failure: The review request is not public.
draft:
bugs:
- '2'
commit: null
summary: Bug 2 - base
@@ -228,16 +230,17 @@ Put some wonky byte sequences in the dif
summary: ''
description: ''
target_people: []
extra_data: {}
commit_extra_data:
p2rb: true
p2rb.identifier: bz://2/mynick
p2rb.is_squashed: false
+ flags: []
diffs: []
approved: false
approval_failure: The review request is not public.
draft:
bugs:
- '2'
commit: null
summary: Bug 2 - tip
--- a/pylib/mozreview/mozreview/extension.py
+++ b/pylib/mozreview/mozreview/extension.py
@@ -88,16 +88,19 @@ from mozreview.resources.commit_data imp
commit_data_resource,
)
from mozreview.resources.commit_rewrite import (
commit_rewrite_resource,
)
from mozreview.resources.ensure_drafts import (
ensure_drafts_resource,
)
+from mozreview.resources.flag import (
+ flag_resource,
+)
from mozreview.resources.modify_reviewer import (
modify_reviewer_resource,
)
from mozreview.resources.review_request_summary import (
review_request_summary_resource,
)
from mozreview.resources.verify_reviewer import (
verify_reviewer_resource,
@@ -192,16 +195,17 @@ class MozReviewExtension(Extension):
batch_review_request_resource,
batch_review_resource,
bugzilla_api_key_login_resource,
commit_data_resource,
commit_rewrite_resource,
employee_ldap_association_resource,
ensure_drafts_resource,
file_diff_reviewer_resource,
+ flag_resource,
ldap_association_resource,
modify_reviewer_resource,
review_request_summary_resource,
try_autoland_trigger_resource,
verify_reviewer_resource,
]
middleware = [
new file mode 100644
--- /dev/null
+++ b/pylib/mozreview/mozreview/managers.py
@@ -0,0 +1,35 @@
+from django.db.models import Manager, Q
+from django.core.exceptions import ObjectDoesNotExist
+
+
+class MozReviewFlagTypeManager(Manager):
+ def get_review_type(self):
+ """Get or create MozReviewFlagType for review."""
+ try:
+ return self.get(name='review')
+ except ObjectDoesNotExist:
+ return self.create(
+ name='review',
+ short_name='r',
+ description='',
+ values_json='["+", "-", "?"]')
+
+
+class MozReviewFlagManager(Manager):
+ def common_filter(self, review_request=None, requestee=None,
+ type_name='review'):
+ """Returns flags of given type and requestee for a request"""
+ q = Q(type__name=type_name)
+
+ if review_request:
+ q = q & Q(review_request__pk=review_request.pk)
+
+ if requestee:
+ q = q & Q(requestee__pk=requestee.pk)
+
+ # make sure the review exists
+ if type_name == 'review':
+ q = q & Q(review__pk__isnull=False,
+ review__base_reply_to__isnull=True)
+
+ return self.filter(q).order_by('-timestamp')
--- a/pylib/mozreview/mozreview/models.py
+++ b/pylib/mozreview/mozreview/models.py
@@ -1,42 +1,53 @@
from __future__ import unicode_literals
+import json
+
from django.contrib.auth.models import User
+from django.core.exceptions import ValidationError
from django.db import models
-from reviewboard.diffviewer.models import FileDiff
+from reviewboard.changedescs.models import ChangeDescription
from mozreview.autoland.models import (
AutolandEventLogEntry,
AutolandRequest
)
from mozreview.bugzilla.models import (
BugzillaUserMap,
get_bugzilla_api_key,
get_or_create_bugzilla_users,
set_bugzilla_api_key,
UnverifiedBugzillaApiKey
)
from mozreview.commits.models import (
CommitData,
DiffSetVerification,
)
+from mozreview.file_diff_reviewer.models import FileDiffReviewer
from mozreview.ldap import query_scm_group
-
-from mozreview.file_diff_reviewer.models import FileDiffReviewer
+from mozreview.managers import (
+ MozReviewFlagManager,
+ MozReviewFlagTypeManager,
+)
+from reviewboard.reviews.models import (
+ ReviewRequest,
+ Review,
+)
__all__ = [
'AutolandEventLogEntry',
'AutolandRequest',
'BugzillaUserMap',
'CommitData',
'DiffSetVerification',
'FileDiffReviewer',
'get_bugzilla_api_key',
'get_or_create_bugzilla_users',
+ 'MozReviewFlag',
'MozReviewUserProfile',
'set_bugzilla_api_key',
'UnverifiedBugzillaApiKey',
]
def get_profile(user):
"""Return the MozReviewUserProfile associated with a user.
@@ -60,17 +71,120 @@ class MozReviewUserProfile(models.Model)
def has_scm_ldap_group(self, group):
"""Return True if the user is a member of the provided ldap group."""
if not self.ldap_username:
return False
return query_scm_group(self.ldap_username, group)
-
class Meta:
app_label = 'mozreview'
permissions = (
("modify_ldap_association",
"Can change ldap assocation for all users"),
("enable_autoland",
"Can enable or disable autoland for a repository"),
)
+
+
+class MozReviewFlagType(models.Model):
+ """Flag Types to be used with class::MozReviewFlag"""
+ # i.e. "review"
+ name = models.CharField(max_length=200, unique=True)
+ # short_name is used for presentation only i.e. 'r'
+ short_name = models.CharField(max_length=4)
+ description = models.TextField(default='')
+ # Returns whether the flagtype is active or disabled.
+ # JSON string reprenting a list of allowed values ex. "['+', '-', '?']"
+ values_json = models.CharField(max_length=200)
+
+ class Meta:
+ verbose_name = 'flag type'
+ app_label = 'mozreview'
+
+ objects = MozReviewFlagTypeManager()
+
+ @property
+ def values(self):
+ return json.loads(self.values_json)
+
+ def get_value_from_status(self, value_name):
+ """Returns a value of the flag if its presentation name was given.
+
+ This is useful to strip flag value from extra_data.
+ For "r?" returns "?"
+ """
+ if not value_name.startswith(self.short_name):
+ raise ValueError('Status should start with the right short_name')
+
+ value = value_name.split(self.short_name, 1)[1]
+ if value not in self.values:
+ raise ValueError('Status (%s) is not allowed' % value_name)
+
+ return value
+
+ def __str__(self):
+ return self.name
+
+
+class MozReviewFlag(models.Model):
+ """MozReview Flag representation in database."""
+ type = models.ForeignKey(MozReviewFlagType)
+ # a value from MozReviewFlagType::values_json (+|-|?)
+ value = models.CharField(max_length=10)
+ review_request = models.ForeignKey(ReviewRequest, related_name='flags')
+ review = models.ForeignKey(Review, related_name='flags',
+ blank=True, null=True)
+ change_description = models.ForeignKey(ChangeDescription,
+ related_name='flags',
+ blank=True, null=True)
+ # user who set the flag
+ setter = models.ForeignKey(User, related_name='flags_set')
+ # user who has been requested to set the flag
+ requestee = models.ForeignKey(User, default=None,
+ related_name='flags_requested',
+ blank=True, null=True)
+ timestamp = models.DateTimeField(auto_now=True)
+
+ class Meta:
+ verbose_name = 'flag'
+ app_label = 'mozreview'
+ get_latest_by = 'timestamp'
+
+ objects = MozReviewFlagManager()
+
+ @property
+ def type_name(self):
+ """Returns name of the related type
+
+ Used primarily in API to avoid creation of the resource for
+ class::MozReviewFlagType
+ """
+ return self.type.name
+
+ @staticmethod
+ def validate_value(value, type, review=None, requestee=None,
+ target_people=[]):
+ """Validate the value.
+
+ It has to be a class method as we validate the flag value in
+ signal_handlers before object is instantiated.
+ """
+ if value not in type.values:
+ raise ValidationError("Value '%s' is not allowed." % value)
+
+ if (review and value == '?'
+ and requestee and requestee not in target_people):
+ raise ValidationError("Value '?' is not allowed for user "
+ "%s." % requestee)
+
+ def full_clean(self, *args, **kwargs):
+ """Check if value is within values allowed by the type"""
+ super(MozReviewFlag, self).full_clean(*args, **kwargs)
+ MozReviewFlag.validate_value(self.value, self.type, self.review,
+ self.requestee,
+ self.review_request.target_people.all())
+
+ def save(self, *args, **kwargs):
+ """Validate and save"""
+ self.full_clean()
+ return super(MozReviewFlag, self).save(*args, **kwargs)
new file mode 100644
--- /dev/null
+++ b/pylib/mozreview/mozreview/resources/flag.py
@@ -0,0 +1,78 @@
+from djblets.webapi.errors import (
+ DOES_NOT_EXIST,
+)
+from reviewboard.reviews.models import (
+ ReviewRequest,
+)
+from reviewboard.webapi.resources import (
+ WebAPIResource,
+)
+
+from mozreview.extra_data import (
+ REVIEW_FLAG_KEY,
+)
+from mozreview.models import (
+ MozReviewFlag,
+)
+
+
+class MozReviewFlagResource(WebAPIResource):
+ """Provides read-only access to MozReviewFlag objects
+
+ This resource is primarily needed for testing to allow the flags
+ related to ReviewRequest to be inspected.
+ """
+
+ name = 'flag'
+ model = MozReviewFlag
+ model_parent_key = 'review-request'
+ allowed_methods = ('GET',)
+
+ def _serialize(self, flag):
+ return {
+ 'id': flag.pk,
+ 'type': flag.type_name,
+ 'value': flag.value,
+ 'review_request': flag.review_request.pk,
+ 'setter': flag.setter.username,
+ 'requestee': flag.requestee.username if flag.requestee else '',
+ 'review': flag.review.pk if flag.review else '',
+ 'review_extra_data_flag': flag.review.extra_data.get(
+ REVIEW_FLAG_KEY, '') if flag.review else '',
+ 'change_description': (flag.change_description.pk
+ if flag.change_description else ''),
+ 'timestamp': flag.timestamp
+ }
+
+ def get_list(self, request, *args, **kwargs):
+ """Return list of flags related to a given review_request_id
+
+ GET attributes:
+ * review-request (int) required, `ReviewRequest` pk
+ """
+ review_request_id = request.GET.get(self.model_parent_key)
+ try:
+ rr = ReviewRequest.objects.get(id=review_request_id)
+ except ReviewRequest.DoesNotExist:
+ return DOES_NOT_EXIST
+
+ if not rr.is_accessible_by(request.user):
+ return self.get_no_access_error(request, *args, **kwargs)
+
+ flags = rr.flags.all()
+
+ data = {
+ 'links': self.get_links(self.list_child_resources,
+ request=request, *args, **kwargs),
+ }
+
+ return self.paginated_cls(
+ request,
+ queryset=flags,
+ results_key=self.list_result_key,
+ serialize_object_func=lambda obj: self._serialize(obj),
+ extra_data=data,
+ **self.build_response_args(request))
+
+
+flag_resource = MozReviewFlagResource()
--- a/pylib/mozreview/mozreview/review_helpers.py
+++ b/pylib/mozreview/mozreview/review_helpers.py
@@ -1,18 +1,19 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, unicode_literals
from reviewboard.reviews.models import ReviewRequestDraft
-from mozreview.extra_data import REVIEW_FLAG_KEY
-from mozreview.models import get_profile
+from mozreview.models import (
+ get_profile,
+)
def gen_latest_reviews(review_request):
"""Generate a series of relevant reviews.
Generates the set of reviews for a review request where there is
only a single review for each user and it is that users most
recent review.
@@ -94,40 +95,38 @@ def get_reviewers_status(review_request,
reviewers = designated_reviewers
# We need to grab the reviews and statuses off the non-draft.
if isinstance(review_request, ReviewRequestDraft):
review_request = review_request.review_request
reviewers_status = dict()
- for r in reviewers:
+ for reviewer in reviewers:
# The initial state is r?
- reviewers_status[r.username] = {
+ reviewers_status[reviewer.username] = {
'ship_it': False,
- 'review_flag': 'r?' if r in designated_reviewers else ' ',
+ 'review_flag': 'r?' if reviewer in designated_reviewers else '',
}
- for review in gen_latest_reviews(review_request):
- review_flag = review.extra_data.get(REVIEW_FLAG_KEY)
- user = review.user.username
+ # Find flags for each review
+ for review_flag in review_request.flags.common_filter():
+ if not review_flag.requestee:
+ break
+ user = review_flag.requestee.username
if (user not in reviewers_status) and include_drive_by:
reviewers_status[user] = {}
if user in reviewers_status:
- reviewers_status[user]['ship_it'] = review.ship_it
- if review_flag:
- reviewers_status[user]['review_flag'] = review_flag
- else:
- # For backwards compatibility.
- if review.ship_it:
- reviewers_status[user]['review_flag'] = 'r+'
- else:
- reviewers_status[user]['review_flag'] = ' '
+ reviewers_status[user] = {
+ 'ship_it': review_flag.review.ship_it,
+ 'review_flag': '%s%s' % (review_flag.type.short_name,
+ review_flag.value)
+ }
return reviewers_status
def has_shipit_carryforward(review_request):
"""Return whether the review request has a carried forward ship-it
A ship-it is considered carried forward if the commit for which it was
--- a/pylib/mozreview/mozreview/signal_handlers.py
+++ b/pylib/mozreview/mozreview/signal_handlers.py
@@ -5,16 +5,19 @@ import json
import logging
from django.contrib.sites.models import (
Site
)
from django.contrib.auth.models import (
User,
)
+from django.core.exceptions import (
+ ValidationError,
+)
from django.db.models.signals import (
post_save,
pre_delete,
pre_save,
)
from djblets.siteconfig.models import (
SiteConfiguration,
@@ -81,24 +84,23 @@ from mozreview.messages import (
AUTO_SUBMITTED_DESCRIPTION,
NEVER_USED_DESCRIPTION,
OBSOLETE_DESCRIPTION,
)
from mozreview.models import (
CommitData,
DiffSetVerification,
get_bugzilla_api_key,
+ MozReviewFlag,
+ MozReviewFlagType,
)
from mozreview.rb_utils import (
get_diff_url,
get_obj_url,
)
-from mozreview.review_helpers import (
- get_reviewers_status,
-)
from mozreview.signals import (
commit_request_publishing,
)
logger = logging.getLogger(__name__)
@@ -210,16 +212,88 @@ def ensure_parent_draft(draft):
parent_rr_draft = parent_rr.get_draft()
if parent_rr_draft is None:
parent_rr_draft = ReviewRequestDraft.create(parent_rr)
update_parent_rr_reviewers(parent_rr_draft)
+def manage_flags_on_rr_publishing(review_request, review_request_draft,
+ user, has_diffset=False):
+ """Manage flags when ReviewRequest is publishing.
+
+ All reviewers flags which are or were in `ReviewRequest`'s `target_people`
+ needs to be amended.
+ Flag of a requestee removed from target_people needs to be either
+ removed or requestee removed from the flag.
+ """
+ if is_parent(review_request):
+ return
+
+ flag_type_review = MozReviewFlagType.objects.get_review_type()
+ review_flags = review_request.flags.filter(type=flag_type_review)
+
+ # Requestees before publishing
+ existing_requestee_set = set(
+ map(lambda f: f.requestee.pk,
+ list(review_flags.filter(requestee__pk__isnull=False))))
+ # Requestees to be published
+ target_requestee_set = set(
+ map(lambda r: r.pk, list(review_request_draft.target_people.all())))
+ # Requestees who created a comment and have been later removed from
+ # target_people list.
+ empty_requestee_set = set(
+ map(lambda f: f.setter.pk,
+ list(review_flags.filter(requestee__pk__isnull=True))))
+
+ if has_diffset:
+ # remove older flags and create new ones for members of
+ # target_people
+ for requestee_pk in existing_requestee_set:
+ review_flags.get(requestee__pk=requestee_pk).delete()
+
+ for requestee_pk in target_requestee_set:
+ MozReviewFlag.objects.create(
+ type=flag_type_review,
+ value='?',
+ review_request=review_request,
+ setter=user,
+ requestee_id=requestee_pk)
+ else:
+ # manage modifications of target_people
+ added_requestee_set = target_requestee_set - existing_requestee_set
+ removed_requestee_set = existing_requestee_set - target_requestee_set
+
+ for requestee_pk in added_requestee_set:
+ if requestee_pk in empty_requestee_set:
+ # readd requestee to the review flag
+ flag = review_flags.get(setter__pk=requestee_pk)
+ flag.requestee_id = requestee_pk
+ flag.save()
+ else:
+ MozReviewFlag.objects.create(
+ type=flag_type_review,
+ value='?',
+ review_request=review_request,
+ setter=user,
+ requestee_id=requestee_pk)
+
+ for requestee_pk in removed_requestee_set:
+ try:
+ review_flags.get(requestee__pk=requestee_pk,
+ review__pk__isnull=True).delete()
+ except MozReviewFlag.DoesNotExist:
+ # there was a review created - remove the requestee
+ # from the flag
+ flag = review_flags.get(requestee__pk=requestee_pk)
+ flag.requestee = None
+ flag.save()
+
+
@bugzilla_to_publish_errors
def on_review_request_publishing(user, review_request_draft, **kwargs):
# There have been strange cases (all local, and during development), where
# when attempting to publish a review request, this handler will fail
# because the draft does not exist. This is a really strange case, and not
# one we expect to happen in production. However, since we've seen it
# locally, we handle it here, and log.
if not review_request_draft:
@@ -227,17 +301,19 @@ def on_review_request_publishing(user, r
'review request we were attempting to publish.')
return
# If the review request draft has a new DiffSet we will only allow
# publishing if that DiffSet has been verified. It is important to
# do this for every review request, not just pushed ones, because
# we can't trust the storage mechanism which indicates it was pushed.
# TODO: This will be fixed when we transition away from extra_data.
+ has_diffset = False
if review_request_draft.diffset:
+ has_diffset = True
try:
DiffSetVerification.objects.get(
diffset=review_request_draft.diffset)
except DiffSetVerification.DoesNotExist:
logger.error(
'An attempt was made by User %s to publish an unverified '
'DiffSet with id %s',
user.id,
@@ -399,16 +475,19 @@ def on_review_request_publishing(user, r
for key in DRAFTED_COMMIT_DATA_KEYS:
if key in commit_data.draft_extra_data:
commit_data.extra_data[key] = commit_data.draft_extra_data[key]
commit_data.save(update_fields=['extra_data'])
review_request.save()
+ manage_flags_on_rr_publishing(review_request, review_request_draft,
+ user, has_diffset)
+
def on_draft_pre_delete(sender, instance, using, **kwargs):
""" Handle draft discards.
There are no handy signals built into Review Board (yet) for us to detect
when a squashed Review Request Draft is discarded. Instead, we monitor for
deletions of models, and handle cases where the models being deleted are
ReviewRequestDrafts. We then do some processing to ensure that the draft
@@ -606,57 +685,105 @@ def pre_save_review(sender, *args, **kwa
review = kwargs["instance"]
if review.pk:
# The review create endpoint calls save twice: the first time it
# gets or creates the review and the second time it updates the
# object retrieved/created. This condition let us execute the code
# below only once.
if not is_parent(review.review_request):
+ if REVIEW_FLAG_KEY not in review.extra_data:
+ try:
+ # Find review_request flag of that user and carry
+ # forward the status
+ status = str(review.review_request.flags.get(
+ requestee=review.user))
+ except MozReviewFlag.DoesNotExist:
+ if (review.user
+ in review.review_request.target_people.all()):
+ status = 'r?'
+ else:
+ status = ''
- if REVIEW_FLAG_KEY not in review.extra_data:
- # TODO: we should use a different query than going through
- # all the reviews, which is what get_reviewers_status does.
- reviewers_status = get_reviewers_status(review.review_request,
- reviewers=[review.user])
- user = review.user.username
- flag = reviewers_status.get(user, {}).get('review_flag', ' ')
- review.extra_data[REVIEW_FLAG_KEY] = flag
+ review.extra_data[REVIEW_FLAG_KEY] = status
review.ship_it = (review.extra_data[REVIEW_FLAG_KEY] == 'r+')
+def get_flag_value(status, review, flag_type_review, user, target_people):
+ """Validate status and return flag_value, log the errors on exceptions"""
+ if status == '':
+ flag_value = None
+ else:
+ try:
+ flag_value = flag_type_review.get_value_from_status(status)
+ except ValueError:
+ logger.error('Did not publish review: %s, wrong value: %s' % (
+ review.id, status))
+ raise
+ try:
+ MozReviewFlag.validate_value(flag_value, flag_type_review, review,
+ user, target_people)
+ except ValidationError:
+ logger.error('Did not publish review: '
+ '%s, invalid flag: %s' % (review.id, status))
+ raise
+
+ return flag_value
+
+
+def save_flag_on_review_publishing(flag_value, flag_type_review, user, review):
+ """Create a new one or update an existing flag"""
+ try:
+ flag = MozReviewFlag.objects.get(
+ type=flag_type_review,
+ review_request=review.review_request,
+ requestee=user)
+ except MozReviewFlag.DoesNotExist:
+ flag = MozReviewFlag(
+ type=flag_type_review,
+ review_request=review.review_request,
+ requestee=user)
+
+ flag.value = flag_value
+ flag.review = review
+ flag.setter = user
+ flag.save()
+ return flag
+
+
@bugzilla_to_publish_errors
def on_review_publishing(user, review, **kwargs):
"""Comment in the bug and potentially r+ or clear a review flag.
Note that a reviewer *must* have editbugs to set an attachment flag on
someone else's attachment (i.e. the standard BMO review process).
TODO: Report lack-of-editbugs properly; see bug 1119065.
"""
review_request = review.review_request
logger.info('Publishing review for user: %s review id: %s '
'review request id: %s' % (user, review.id,
- review_request.id))
+ review_request.id))
# skip review requests that were not pushed
if not is_pushed(review_request):
logger.info('Did not publish review: %s: for user: %d: review not '
'pushed.' % (user, review.id))
return
site = Site.objects.get_current()
siteconfig = SiteConfiguration.objects.get_current()
comment = build_plaintext_review(review,
get_obj_url(review, site,
siteconfig),
{"user": user})
b = Bugzilla(get_bugzilla_api_key(user))
+ flag_value = False
if is_parent(review_request):
# We only support raw comments on parent review requests to prevent
# confusion. If the ship-it flag or the review flag was set, throw
# an error.
# Otherwise, mirror the comment over, associating it with the first
# commit.
if review.ship_it or review.extra_data.get(REVIEW_FLAG_KEY):
raise ParentShipItError
@@ -667,36 +794,55 @@ def on_review_publishing(user, review, *
first_child = list(gen_child_rrs(review_request))[0]
b.post_comment(int(first_child.get_bug_list()[0]), comment,
get_diff_url(first_child), False)
else:
diff_url = get_diff_url(review_request)
bug_id = int(review_request.get_bug_list()[0])
commented = False
- flag = review.extra_data.get(REVIEW_FLAG_KEY)
+ status = review.extra_data.get(REVIEW_FLAG_KEY)
+
+ flag_type_review = MozReviewFlagType.objects.get_review_type()
- if flag is not None:
- commented = b.set_review_flag(bug_id, flag, review.user.email,
+ if status is not None:
+ flag_value = None
+ try:
+ flag_value = get_flag_value(status, review, flag_type_review,
+ user,
+ review_request.target_people.all())
+ except ValidationError:
+ pass
+ except ValueError:
+ pass
+
+ # Set status in Bugzilla.
+ commented = b.set_review_flag(bug_id, status, review.user.email,
diff_url, comment)
else:
# If for some reasons we don't have the flag set in extra_data,
# fall back to ship_it
logger.warning('Review flag not set on review %s, '
'updating attachment based on ship_it' % review.id)
if review.ship_it:
+ # setting the status to create a flag later
+ flag_value = '+'
commented = b.r_plus_attachment(bug_id, review.user.email,
diff_url, comment)
else:
commented = b.cancel_review_request(bug_id, review.user.email,
diff_url, comment)
if comment and not commented:
b.post_comment(bug_id, comment, diff_url, False)
+ if flag_value:
+ save_flag_on_review_publishing(flag_value, flag_type_review,
+ user, review)
+
def get_reply_url(reply, site=None, siteconfig=None):
""" Get the URL for a reply to a review.
Since replies can have multiple comments, we can't link to a specific
comment, so we link to the parent review which the reply is targeted at.
"""
return get_obj_url(reply.base_reply_to, site=site, siteconfig=siteconfig)
--- a/pylib/mozreview/mozreview/static/mozreview/js/review_flag.js
+++ b/pylib/mozreview/mozreview/static/mozreview/js/review_flag.js
@@ -1,29 +1,33 @@
/**
* MRReviewFlag is responsible for showing the r?, r+, r- select dropdown
* in the review dialog. It will also do the work of setting the extraData
* in a Review model with the value that the user selects.
*/
MRReviewFlag = {};
+// Choose a set of flags to be displayed in the drop-down based on the
+// ReviewRequest::target_people list
+var is_designated_reviewer = $('#user_data').data('is-designated-reviewer');
+const REVIEW_FLAG_STATES = [['', 'r+', 'r-'], ['r?', 'r+', 'r-']][is_designated_reviewer];
MRReviewFlag.View = Backbone.View.extend({
/**
* If we save state, it'll be to a Review's extraData using this
* key. This is the js counterpart of mozreview.extra_data.REVIEW_FLAG_KEY
*/
key: 'p2rb.review_flag',
/**
* These are the possible states that will be shown in the dropdown,
* in order. These are also the values that will be stored in the
* extraData field.
*/
- states: [' ', 'r?', 'r+', 'r-'],
+ states: REVIEW_FLAG_STATES,
template: _.template([
'<label for="mr-review-flag" hidden>Review state:</label> ',
'<select id="mr-review-flag">',
'<% _(states).each(function(state) { %>',
' <option <% if (state === val) { %> selected <% } %> >',
' <%= state %>',
' </option>',
--- a/pylib/mozreview/mozreview/templates/mozreview/user-data.html
+++ b/pylib/mozreview/mozreview/templates/mozreview/user-data.html
@@ -1,10 +1,11 @@
{% load mozreview %}
<div id="user_data"
data-scm-level="{{ request.mozreview_profile|scm_level }}"
{% if request.user.is_authenticated and review_request %}
data-last-reviewed-revision="{{ review_request|data_reviewed_revision:request.user }}"
{% if review_request.submitter.id == request.user.id %}
data-is-submitter="true"
{% endif %}
+ data-is-designated-reviewer="{{ review_request|is_designated_reviewer:request.user }}"
{% endif %}
></div>
--- a/pylib/mozreview/mozreview/templatetags/mozreview.py
+++ b/pylib/mozreview/mozreview/templatetags/mozreview.py
@@ -76,16 +76,24 @@ def scm_level(mozreview_profile):
def data_reviewed_revision(review_request, user):
"""Return the latest diff revision a user reviewed.
`0`, a revision number which will never exist, is returned
if the user has not performed a review.
"""
return latest_revision_reviewed(review_request, user=user) or 0
+@register.filter()
+def is_designated_reviewer(review_request, user):
+ """Check if registered user is in listed in review_request's target_people
+
+ Returns 0 or 1
+ """
+ return review_request.target_people.filter(pk=user.pk).count()
+
@register.filter()
def required_ldap_group(repository):
try:
return repository.extra_data['required_ldap_group']
except (AttributeError, KeyError):
return ''
--- a/testing/vcttesting/reviewboard/mach_commands.py
+++ b/testing/vcttesting/reviewboard/mach_commands.py
@@ -35,16 +35,46 @@ def dict_from_diff(diff):
d['revision'] = diff.revision
d['base_commit_id'] = diff.base_commit_id
d['name'] = diff.name
d['extra'] = dict(diff.extra_data.iteritems())
d['patch'] = diff.get_patch().data.splitlines()
return d
+def serialize_flag(flag):
+ d = OrderedDict()
+ d['id'] = flag['id']
+ d['type'] = flag['type']
+ d['value'] = flag['value']
+ d['review_request'] = flag['review_request']
+ d['setter'] = flag['setter']
+ d['requestee'] = flag['requestee']
+ d['review'] = flag['review']
+ d['review_extra_data_flag'] = flag['review_extra_data_flag']
+ d['change_description'] = flag['change_description']
+ d['timestamp'] = flag['timestamp']
+ return d
+
+
+def get_and_serialize_flags(api_client, rr):
+ flags_res = api_client.get_path(
+ '/extensions/mozreview.extension.MozReviewExtension/flags/',
+ review_request=rr.id)
+ flags = []
+ for flag in flags_res:
+ flags.append(serialize_flag(flag))
+ return flags
+
+def serialize_flags(api_client, rr):
+ d = OrderedDict()
+ d['review_request_id'] = rr.id
+ d['flags'] = get_and_serialize_flags(api_client, rr)
+ return yaml.safe_dump(d, default_flow_style=False).rstrip()
+
def serialize_review_requests(api_client, rr):
from rbtools.api.errors import APIError
d = OrderedDict()
d['id'] = rr.id
d['status'] = rr.status
d['public'] = rr.public
d['bugs'] = list(rr.bugs_closed)
d['commit'] = rr.commit_id
@@ -54,16 +84,18 @@ def serialize_review_requests(api_client
d['target_people'] = [p.get().username for p in rr.target_people]
d['extra_data'] = dict(rr.extra_data.iteritems())
commit_data = api_client.get_path(
'/extensions/mozreview.extension.MozReviewExtension/commit-data/%s/' %
rr.id)
d['commit_extra_data'] = dict(commit_data.extra_data.iteritems())
+ d['flags'] = get_and_serialize_flags(api_client, rr)
+
d['diffs'] = []
for diff in rr.get_diffs():
d['diffs'].append(dict_from_diff(diff))
d['approved'] = rr.approved
d['approval_failure'] = rr.approval_failure
review_list = rr.get_reviews(review_request_id=rr.id)
@@ -233,16 +265,25 @@ class ReviewBoardCommands(object):
description='Print a representation of a review request.')
@CommandArgument('rrid', help='Review request id to dump')
def dumpreview(self, rrid):
client = self._get_client()
root = client.get_root()
r = root.get_review_request(review_request_id=rrid)
print(serialize_review_requests(client, r))
+ @Command('dumpflags', category='reviewboard',
+ description='Print a representation of flags for a review request')
+ @CommandArgument('rrid', help='Review request id')
+ def dumpflags(self, rrid):
+ client = self._get_client()
+ root = client.get_root()
+ r = root.get_review_request(review_request_id=rrid)
+ print serialize_flags(client, r)
+
@Command('dump-raw-diff', category='reviewboard',
description='Dump the raw content of a diff from the server')
@CommandArgument('rrid', help='Review request id of diffs to dump')
def dump_raw_diff(self, rrid):
from rbtools.api.errors import APIError
client = self._get_client()
root = client.get_root()
@@ -436,18 +477,21 @@ class ReviewBoardCommands(object):
if body_bottom:
args['body_bottom'] = body_bottom
if body_top:
args['body_top'] = body_top
try:
r = reviews.create(**args)
except APIError as e:
- print('API Error: %s: %s: %s' % (e.http_status, e.error_code,
- e.rsp['err']['msg']))
+ if e.rsp:
+ print('API Error: %s: %s: %s' % (e.http_status, e.error_code,
+ e.rsp['err']['msg']))
+ else:
+ print('API Error: %s: %s' % (e.http_status, e))
return 1
print('created review %s' % r.rsp['review']['id'])
@Command('publish-review', category='reviewboard',
description='Publish a review')
@CommandArgument('rrid', help='Review request review is attached to')
@CommandArgument('rid', help='Review to publish')