This is an automated email from the ASF dual-hosted git repository.
sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git
The following commit(s) were added to refs/heads/master by this push:
new fd5f490 Tests of management interface
fd5f490 is described below
commit fd5f49099d7e034e6c8188f7f4436ae061724986
Author: Sebb <[email protected]>
AuthorDate: Sat Jan 29 16:49:19 2022 +0000
Tests of management interface
---
.github/workflows/integration-tests.yml | 1 +
test/itest_integration.py | 246 ++++++++++++++++-----
.../resources/dev_ponymail_apache_org_2020-10.mbox | 120 ++++++++++
3 files changed, 316 insertions(+), 51 deletions(-)
diff --git a/.github/workflows/integration-tests.yml
b/.github/workflows/integration-tests.yml
index 96efada..8a4a50a 100644
--- a/.github/workflows/integration-tests.yml
+++ b/.github/workflows/integration-tests.yml
@@ -75,6 +75,7 @@ jobs:
# The early messages were under incubator ...
tools/import-mbox.py --source
test/resources/users_ponymail_apache_org_2019-09.mbox --private --lid
users.ponymail.apache.org
tools/import-mbox.py --source
test/resources/users_ponymail_apache_org_2022-01.mbox
+ tools/import-mbox.py --source
test/resources/dev_ponymail_apache_org_2020-10.mbox
- name: Server
run: |
cd server
diff --git a/test/itest_integration.py b/test/itest_integration.py
index 89900d4..010e11d 100644
--- a/test/itest_integration.py
+++ b/test/itest_integration.py
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import time
import pytest
import random
import requests
@@ -22,6 +23,12 @@ import requests
# Run as: python3 -m pytest [-s] test/itest_integration.py
API_BASE='http://localhost:8080/api'
+TEST_DOMAIN = 'ponymail.apache.org'
+TEST_LIST = 'users'
+TEST_LIST2 = 'dev'
+DOCUMENT_HIDE_TEST = "c396ps3p5pb05srb4269dzcg9j7sof42"
+DOCUMENT_EDIT_TEST = "ffc3s2wzpn4n4pfonk9rffs4mnbk3l65" # dev list
+DOCUMENT_EDIT_SOURCE =
"a05f5a472b5e7e6d0ea10162fa9d2b499861258c142dbb7f402454ad23b4af46"
# Emulate how test auth is used by GUI
def get_cookies(user='user'):
@@ -37,77 +44,108 @@ def get_cookies(user='user'):
assert 'credentials' in jzon['login']
return cookies
-def check_access(email, cookies):
- # check email accessibility
- mid = email['mid']
+def check_email(email, cookies):
+ # check email accessibility
+ mid = email['mid']
+ private = email['private']
+
+ # access by Permalink
+ res = requests.get(
+ f"{API_BASE}/email.lua",
+ params={"id": mid},
+ cookies=cookies
+ )
+ assert res.status_code == 200, mid
+ jzon = res.json()
+ assert mid == jzon['mid']
+ assert mid in jzon['permalinks']
+
+ # check email access by message-id
+ msgid = jzon['message-id']
+ listid = jzon['list_raw']
+ res = requests.get(
+ f"{API_BASE}/email.lua",
+ params={"id": msgid, "listid": listid},
+ cookies=cookies
+ )
+ assert res.status_code == 200, msgid
+ if private:
+ # should not be visible without cookies
res = requests.get(
f"{API_BASE}/email.lua",
- params={"id": mid},
- cookies=cookies
+ params={"id": mid}
)
- assert res.status_code == 200
- jzon = res.json()
- assert mid == jzon['mid']
- assert mid in jzon['permalinks']
- # check email access by message-id
- msgid = jzon['message-id']
- listid = jzon['list_raw']
+ assert res.status_code == 404, mid
res = requests.get(
f"{API_BASE}/email.lua",
- params={"id": msgid, "listid": listid},
- cookies=cookies
+ params={"id": msgid, "listid": listid}
)
- assert res.status_code == 200
- if email['private']:
- # should not be visible without cookies
- res = requests.get(
- f"{API_BASE}/email.lua",
- params={"id": mid}
- )
- assert res.status_code == 404
- res = requests.get(
- f"{API_BASE}/email.lua",
- params={"id": msgid, "listid": listid}
- )
- assert res.status_code == 404
- # check source accessibility
+ assert res.status_code == 404, msgid
+ return mid, msgid, listid, private
+
+def check_source(mid, msgid, listid, private, cookies):
+ res = requests.get(
+ f"{API_BASE}/source.lua",
+ params={"id": mid},
+ cookies=cookies
+ )
+ assert res.status_code == 200, mid
+ res = requests.get(
+ f"{API_BASE}/source.lua",
+ params={"id": msgid, "listid": listid},
+ cookies=cookies
+ )
+ assert res.status_code == 200, mid
+ if private:
+ # should not be visible without cookies
res = requests.get(
f"{API_BASE}/source.lua",
- params={"id": mid},
- cookies=cookies
+ params={"id": mid}
)
- assert res.status_code == 200
+ assert res.status_code == 404, mid
res = requests.get(
f"{API_BASE}/source.lua",
- params={"id": msgid, "listid": listid},
- cookies=cookies
+ params={"id": msgid, "listid": listid}
)
- assert res.status_code == 200
- if email['private']:
- # should not be visible without cookies
- res = requests.get(
- f"{API_BASE}/source.lua",
- params={"id": mid}
- )
- assert res.status_code == 404
- res = requests.get(
- f"{API_BASE}/source.lua",
- params={"id": msgid, "listid": listid}
- )
- assert res.status_code == 404
+ assert res.status_code == 404, mid
+
+def check_access(email, cookies):
+ mid, msgid, listid, private = check_email(email, cookies)
+ check_source(mid, msgid, listid, private, cookies)
+
+def test_setup():
+ # ensure test conditions are correct at the start
+ import yaml
+ yaml = yaml.safe_load(open("server/ponymail.yaml"))
+ dburl = yaml['database']['dburl']
+ from requests.compat import urljoin
+ path = urljoin(dburl, "ponymail-auditlog/_delete_by_query")
+ res = requests.post(
+ path,
+ json={ "query": { "match_all": {} }},
+ headers={"Content-Type": 'application/json'}
+ )
+ assert res.status_code == 200
+ path = urljoin(dburl, f"ponymail-source/_update/{DOCUMENT_EDIT_SOURCE}")
+ res = requests.post(
+ path,
+ json={ "doc": {"deleted": False} },
+ headers={"Content-Type": 'application/json'}
+ )
+ assert res.status_code == 200
def test_lists():
jzon = requests.get(f"{API_BASE}/preferences").json()
# print(jzon)
lists = jzon['lists']
- assert 'ponymail.apache.org' in lists
- assert 'users' in lists['ponymail.apache.org']
+ assert TEST_DOMAIN in lists
+ assert TEST_LIST in lists[TEST_DOMAIN]
assert len(lists) == 1 # only expecting one domain
def test_public_stats():
jzon = requests.get(
f"{API_BASE}/stats.lua",
- params={"list": 'users', "domain": 'ponymail.apache.org',
"emailsOnly": True, "d": 'gte=0d'}
+ params={"list": TEST_LIST, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": 'gte=0d'}
).json()
assert jzon['firstYear'] == 2022
assert jzon['firstMonth'] == 1
@@ -123,7 +161,7 @@ def test_public_stats():
# Check we cannot see the private emails
jzon = requests.get(
f"{API_BASE}/stats.lua",
- params={"list": 'users', "domain": 'ponymail.apache.org',
"emailsOnly": True, "d": '2019-09'}
+ params={"list": TEST_LIST, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": '2019-09'}
).json()
assert jzon['hits'] == 0
@@ -132,7 +170,7 @@ def test_private_stats():
# only fetch the private mail stats
jzon = requests.get(
f"{API_BASE}/stats.lua",
- params={"list": 'users', "domain": 'ponymail.apache.org',
"emailsOnly": True, "d": '2019-09'},
+ params={"list": TEST_LIST, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": '2019-09'},
cookies=cookies
).json()
# The earlier mails are private
@@ -197,3 +235,109 @@ def test_mgmt_validation():
{"action": 'edit', "document": '1234', "from": 'sender', "subject":
'Test Email', "list": 'abc', "body": 'body'},
admin_cookies, 404)
assert "Email not found!" in text
+
+def test_mgmt_log_before():
+ admin_cookies = get_cookies('admin')
+ jzon = mgmt_get_json({"action": 'log'}, admin_cookies)
+ assert len(jzon['entries']) == 0
+
+def test_mgmt_hiding():
+ admin_cookies = get_cookies('admin')
+
+ # reset in case of earlier failure
+ text = mgmt_get_text({"action": 'unhide', "document": DOCUMENT_HIDE_TEST},
admin_cookies)
+ assert text == "Unhid 1 emails from archives."
+
+ jzon = requests.get(
+ f"{API_BASE}/stats.lua",
+ params={"list": TEST_LIST, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": 'gte=0d'}
+ ).json()
+
+ assert jzon['hits'] == 6
+
+ check_access({"mid": DOCUMENT_HIDE_TEST, "private": False}, admin_cookies)
+
+ text = mgmt_get_text({"action": 'hide', "document": DOCUMENT_HIDE_TEST},
admin_cookies)
+ assert text == "Hid 1 emails from archives."
+
+ jzon = requests.get(
+ f"{API_BASE}/stats.lua",
+ params={"list": TEST_LIST, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": 'gte=0d'}
+ ).json()
+ assert jzon['hits'] == 5
+
+
+
+ text = mgmt_get_text({"action": 'unhide', "document": DOCUMENT_HIDE_TEST},
admin_cookies)
+ assert text == "Unhid 1 emails from archives."
+
+ jzon = requests.get(
+ f"{API_BASE}/stats.lua",
+ params={"list": TEST_LIST, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": 'gte=0d'}
+ ).json()
+ assert jzon['hits'] == 6
+
+ check_access({"mid": DOCUMENT_HIDE_TEST, "private": False}, None)
+
+def test_mgmt_edit():
+ """This test causes the source for an entry to be hidden"""
+ admin_cookies = get_cookies('admin')
+
+ test_list_id = f"<{TEST_LIST2}.{TEST_DOMAIN}>"
+ jzon = requests.get(
+ f"{API_BASE}/stats.lua",
+ params={"list": TEST_LIST2, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": 'gte=0d'}
+ ).json()
+
+ assert jzon['hits'] == 1
+
+ email = jzon['emails'][0]
+ check_access(email, None) # should be fully accessible
+
+ res = requests.get(
+ f"{API_BASE}/mbox.lua",
+ params={"list": TEST_LIST2, "domain": TEST_DOMAIN, "d": '2020-10'}
+ )
+ assert res.status_code == 200
+ assert res.text.startswith('From dev-return-')
+
+ # N.B. use variable body so it is always changed, even after a reset
+ text = mgmt_get_text(
+ {
+ "action": 'edit', "document": DOCUMENT_EDIT_TEST,
+ "from": '', "subject": '', "list": test_list_id, "body":
time.time(), "private": False,
+ },
+ admin_cookies
+ )
+ assert text == "Email successfully saved"
+
+ jzon = requests.get(
+ f"{API_BASE}/stats.lua",
+ params={"list": TEST_LIST2, "domain": TEST_DOMAIN, "emailsOnly": True,
"d": 'gte=0d'}
+ ).json()
+
+ assert jzon['hits'] == 1 # mbox entry still accessible
+
+ check_email(email, None)
+ check_access(email, admin_cookies) # but the source needs admin
+
+ # check that cannot see mbox
+ res = requests.get(
+ f"{API_BASE}/mbox.lua",
+ params={"list": TEST_LIST2, "domain": TEST_DOMAIN, "d": '2020-10'}
+ )
+ assert res.status_code == 200
+ assert len(res.text) <= 1 # probably just LF
+
+ res = requests.get(
+ f"{API_BASE}/mbox.lua",
+ params={"list": TEST_LIST2, "domain": TEST_DOMAIN, "d": '2020-10'},
+ cookies=admin_cookies
+ )
+ assert res.status_code == 200
+ assert res.text.startswith('From dev-return-')
+
+def test_mgmt_log_after():
+ admin_cookies = get_cookies('admin')
+ jzon = mgmt_get_json({"action": 'log'}, admin_cookies)
+ assert len(jzon['entries']) == 4
diff --git a/test/resources/dev_ponymail_apache_org_2020-10.mbox
b/test/resources/dev_ponymail_apache_org_2020-10.mbox
new file mode 100644
index 0000000..4015024
--- /dev/null
+++ b/test/resources/dev_ponymail_apache_org_2020-10.mbox
@@ -0,0 +1,120 @@
+From dev-return-1307-archive-asf-public=cust-asf.ponee...@ponymail.apache.org
Mon Oct 5 04:41:25 2020
+Return-Path:
<dev-return-1307-archive-asf-public=cust-asf.ponee...@ponymail.apache.org>
+X-Original-To: [email protected]
+Delivered-To: [email protected]
+Received: from mxout1-he-de.apache.org (mxout1-he-de.apache.org
[95.216.194.37])
+ by mx-eu-01.ponee.io (Postfix) with ESMTPS id E6FDD180654
+ for <[email protected]>; Mon, 5 Oct 2020 06:41:25
+0200 (CEST)
+Received: from mail.apache.org (mailroute1-lw-us.apache.org [207.244.88.153])
+ by mxout1-he-de.apache.org (ASF Mail Server at mxout1-he-de.apache.org)
with SMTP id 59A9664274
+ for <[email protected]>; Mon, 5 Oct 2020 04:41:25
+0000 (UTC)
+Received: (qmail 7680 invoked by uid 500); 5 Oct 2020 04:41:24 -0000
+Mailing-List: contact [email protected]; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:[email protected]>
+List-Unsubscribe: <mailto:[email protected]>
+List-Post: <mailto:[email protected]>
+List-Id: <dev.ponymail.apache.org>
+Reply-To: [email protected]
+Delivered-To: mailing list [email protected]
+Received: (qmail 7503 invoked by uid 99); 5 Oct 2020 04:41:24 -0000
+Received: from spamproc1-he-de.apache.org (HELO spamproc1-he-de.apache.org)
(116.203.196.100)
+ by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Oct 2020 04:41:24 +0000
+Received: from localhost (localhost [127.0.0.1])
+ by spamproc1-he-de.apache.org (ASF Mail Server at
spamproc1-he-de.apache.org) with ESMTP id 5676B1FF39B
+ for <[email protected]>; Mon, 5 Oct 2020 04:41:23 +0000 (UTC)
+X-Virus-Scanned: Debian amavisd-new at spamproc1-he-de.apache.org
+X-Spam-Flag: NO
+X-Spam-Score: -7.989
+X-Spam-Level:
+X-Spam-Status: No, score=-7.989 tagged_above=-999 required=6.31
+ tests=[ENV_AND_HDR_SPF_MATCH=-0.5, KAM_DMARC_STATUS=0.01,
+ RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_PASS=-0.001,
+ USER_IN_DEF_SPF_WL=-7.5] autolearn=disabled
+Received: from mx1-ec2-va.apache.org ([116.203.227.195])
+ by localhost (spamproc1-he-de.apache.org [116.203.196.100])
(amavisd-new, port 10024)
+ with ESMTP id EhMTXjnR7AGw for <[email protected]>;
+ Mon, 5 Oct 2020 04:41:22 +0000 (UTC)
+Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=3.227.148.255;
helo=mxout1-ec2-va.apache.org; [email protected];
receiver=<UNKNOWN>
+Received: from mxout1-ec2-va.apache.org (mxout1-ec2-va.apache.org
[3.227.148.255])
+ by mx1-ec2-va.apache.org (ASF Mail Server at mx1-ec2-va.apache.org)
with ESMTPS id 8FAB4BC2AF
+ for <[email protected]>; Mon, 5 Oct 2020 04:41:22
+0000 (UTC)
+Received: from mail.apache.org (mailroute1-lw-us.apache.org [207.244.88.153])
+ by mxout1-ec2-va.apache.org (ASF Mail Server at
mxout1-ec2-va.apache.org) with SMTP id 7C8B642544
+ for <[email protected]>; Mon, 5 Oct 2020 04:41:22
+0000 (UTC)
+Received: (qmail 7326 invoked by uid 99); 5 Oct 2020 04:41:22 -0000
+Received: from Unknown (HELO mailrelay1-lw-us.apache.org) (10.10.3.159)
+ by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Oct 2020 04:41:22 +0000
+Received: from macbook-pro-3.hub (unknown [101.114.76.121])
+ by mailrelay1-lw-us.apache.org (ASF Mail Server at
mailrelay1-lw-us.apache.org) with ESMTPSA id C455E40B90
+ for <[email protected]>; Mon, 5 Oct 2020 04:41:21
+0000 (UTC)
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: Podling Ponymail Report Reminder - October 2020
+From: [email protected]
+Date: Mon, 05 Oct 2020 04:41:21 -0000
+To: [email protected]
+Message-ID: <[email protected]>
+
+Dear podling,
+
+This email was sent by an automated system on behalf of the Apache
+Incubator PMC. It is an initial reminder to give you plenty of time to
+prepare your quarterly board report.
+
+The board meeting is scheduled for Wed, 21 October 2020.
+The report for your podling will form a part of the Incubator PMC
+report. The Incubator PMC requires your report to be submitted 2 weeks
+before the board meeting, to allow sufficient time for review and
+submission (Wed, October 07).
+
+Please submit your report with sufficient time to allow the Incubator
+PMC, and subsequently board members to review and digest. Again, the
+very latest you should submit your report is 2 weeks prior to the board
+meeting.
+
+Candidate names should not be made public before people are actually
+elected, so please do not include the names of potential committers or
+PPMC members in your report.
+
+Thanks,
+
+The Apache Incubator PMC
+
+Submitting your Report
+
+----------------------
+
+Your report should contain the following:
+
+* Your project name
+* A brief description of your project, which assumes no knowledge of
+ the project or necessarily of its field
+* A list of the three most important issues to address in the move
+ towards graduation.
+* Any issues that the Incubator PMC or ASF Board might wish/need to be
+ aware of
+* How has the community developed since the last report
+* How has the project developed since the last report.
+* How does the podling rate their own maturity.
+
+This should be appended to the Incubator Wiki page at:
+
+https://cwiki.apache.org/confluence/display/INCUBATOR/October2020
+
+Note: This is manually populated. You may need to wait a little before
+this page is created from a template.
+
+Note: The format of the report has changed to use markdown.
+
+Mentors
+-------
+
+Mentors should review reports for their project(s) and sign them off on
+the Incubator wiki page. Signing off reports shows that you are
+following the project - projects that are not signed may raise alarms
+for the Incubator PMC.
+
+Incubator PMC
+