From 1a4ec25e71a3a5b310fd9bb71bcd5632839fd25d Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Thu, 21 Nov 2024 09:58:17 +0100 Subject: [PATCH 1/5] WIP: Fix tests to support multipart 1.x+ versions. --- CHANGES.rst | 2 +- .../authentication/browser/groupfolder.rst | 661 +++++------------- .../browser/tests/test_doctests.py | 11 +- 3 files changed, 198 insertions(+), 476 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index bd04213..75bf611 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Changes 5.1 (unreleased) ---------------- -- Nothing changed yet. +- Fix tests to support multipart 1.x+ versions. 5.0 (2023-02-09) diff --git a/src/zope/app/authentication/browser/groupfolder.rst b/src/zope/app/authentication/browser/groupfolder.rst index 92ceb2e..c81b065 100644 --- a/src/zope/app/authentication/browser/groupfolder.rst +++ b/src/zope/app/authentication/browser/groupfolder.rst @@ -18,7 +18,6 @@ First, We need to create and register a pluggable authentication utility. >>> print(http(r""" ... POST /++etc++site/default/@@contents.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 98 ... Content-Type: application/x-www-form-urlencoded ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication @@ -38,426 +37,221 @@ First, We need to create and register a pluggable authentication utility. Register PAU. - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.comment', ''), + ... ('field.actions.register', 'Register')]) + >>> print(http(b""" ... POST /++etc++site/default/PAU/addRegistration.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 687 - ... Content-Type: multipart/form-data; boundary=---------------------------5559795404609280911441883437 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs ... Referer: http://localhost/++etc++site/default/PAU/addRegistration.html ... - ... -----------------------------5559795404609280911441883437 - ... Content-Disposition: form-data; name="field.comment" - ... - ... - ... -----------------------------5559795404609280911441883437 - ... Content-Disposition: form-data; name="field.actions.register" - ... - ... Register - ... -----------------------------5559795404609280911441883437-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... Add a Principal folder plugin `users` to PAU. - >>> print(http(r""" - ... POST /++etc++site/default/PAU/+/AddPrincipalFolder.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.prefix', 'users'), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'users')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/+/AddPrincipalFolder.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 429 - ... Content-Type: multipart/form-data; boundary=---------------------------95449631112274213651507932125 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs ... Referer: http://localhost/++etc++site/default/PAU/+/AddPrincipalFolder.html= ... - ... -----------------------------95449631112274213651507932125 - ... Content-Disposition: form-data; name="field.prefix" - ... - ... users - ... -----------------------------95449631112274213651507932125 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------95449631112274213651507932125 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... users - ... -----------------------------95449631112274213651507932125-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... Next we will add some users. - >>> print(http(r""" - ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'bob'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', '123'), + ... ('field.title', 'Bob'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', '')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 780 - ... Content-Type: multipart/form-data; boundary=---------------------------5110544421083023415453147877 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs - ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.login" - ... - ... bob - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.password" - ... - ... 123 - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.title" - ... - ... Bob - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="add_input_name" - ... + ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D ... - ... -----------------------------5110544421083023415453147877-- - ... """, handle_errors=False)) + ... %b + ... """ % (content_type, content), handle_errors=False)) HTTP/1.1 303 See Other ... - - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'bill'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', '123'), + ... ('field.title', 'Bill'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', '')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 780 - ... Content-Type: multipart/form-data; boundary=---------------------------5110544421083023415453147877 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs - ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.login" - ... - ... bill - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.password" - ... - ... 123 - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.title" - ... - ... Bill - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" + ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D ... - ... Add - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... - ... -----------------------------5110544421083023415453147877-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'joe'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', '123'), + ... ('field.title', 'Joe'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', '')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 780 - ... Content-Type: multipart/form-data; boundary=---------------------------5110544421083023415453147877 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs - ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.login" - ... - ... betty - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.password" - ... - ... 123 - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.title" - ... - ... Betty - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.description" + ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D ... - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... - ... -----------------------------5110544421083023415453147877-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'sally'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', '123'), + ... ('field.title', 'Sally'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', '')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 780 - ... Content-Type: multipart/form-data; boundary=---------------------------5110544421083023415453147877 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs - ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.login" - ... - ... sally - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.password" + ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D ... - ... 123 - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.title" - ... - ... Sally - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... - ... -----------------------------5110544421083023415453147877-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'betty'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', '123'), + ... ('field.title', 'Betty'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', '')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 780 - ... Content-Type: multipart/form-data; boundary=---------------------------5110544421083023415453147877 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs - ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.login" + ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D ... - ... george - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.password" - ... - ... 123 - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.title" - ... - ... George - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... - ... -----------------------------5110544421083023415453147877-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'mary'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', '123'), + ... ('field.title', 'Mary'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', '')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 780 - ... Content-Type: multipart/form-data; boundary=---------------------------5110544421083023415453147877 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs - ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.login" - ... - ... mike - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.password" - ... - ... 123 - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.title" - ... - ... Mike - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="add_input_name" + ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D ... - ... - ... -----------------------------5110544421083023415453147877-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'mike'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', '123'), + ... ('field.title', 'Mike'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', '')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 780 - ... Content-Type: multipart/form-data; boundary=---------------------------5110544421083023415453147877 + ... Content-Type: %b ... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs - ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%3D - ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.login" - ... - ... mary - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.password" - ... - ... 123 - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.title" - ... - ... Mary - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="field.description" - ... + ... Referer: http://localhost/++etc++site/default/PAU/users/+/AddPrincipalInformation.html%%3D ... - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------5110544421083023415453147877 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... - ... -----------------------------5110544421083023415453147877-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... Next, We'll add out group folder plugin in PAU. - >>> print(http(r""" - ... POST /++etc++site/default/PAU/+/AddGroupFolder.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.prefix', 'groups'), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'groups')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/+/AddGroupFolder.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 427 - ... Content-Type: multipart/form-data; boundary=---------------------------4150524541658557772058105275 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/+/AddGroupFolder.html= ... - ... -----------------------------4150524541658557772058105275 - ... Content-Disposition: form-data; name="field.prefix" - ... - ... groups - ... -----------------------------4150524541658557772058105275 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------4150524541658557772058105275 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... groups - ... -----------------------------4150524541658557772058105275-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... Next we'll select the credentials and authenticators for the PAU: - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.credentialsPlugins.to', 'U2Vzc2lvbiBDcmVkZW50aWFscw=='), + ... ('field.credentialsPlugins-empty-marker', ''), + ... ('field.authenticatorPlugins.to', 'dXNlcnM='), + ... ('field.authenticatorPlugins.to', 'Z3JvdXBz'), + ... ('field.authenticatorPlugins-empty-marker', ''), + ... ('UPDATE_SUBMIT', 'Change'), + ... ('field.credentialsPlugins', 'U2Vzc2lvbiBDcmVkZW50aWFscw=='), + ... ('field.authenticatorPlugins', 'dXNlcnM='), + ... ('field.authenticatorPlugins', 'Z3JvdXBz')]) + >>> print(http(b""" ... POST /++etc++site/default/PAU/@@configure.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 1313 - ... Content-Type: multipart/form-data; boundary=---------------------------2026736768606413562109112352 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/@@configure.html ... - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.credentialsPlugins.to" - ... - ... U2Vzc2lvbiBDcmVkZW50aWFscw== - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.credentialsPlugins-empty-marker" - ... - ... - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.authenticatorPlugins.to" - ... - ... dXNlcnM= - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.authenticatorPlugins.to" - ... - ... Z3JvdXBz - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.authenticatorPlugins-empty-marker" - ... - ... - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Change - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.credentialsPlugins" - ... - ... U2Vzc2lvbiBDcmVkZW50aWFscw== - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.authenticatorPlugins" - ... - ... dXNlcnM= - ... -----------------------------2026736768606413562109112352 - ... Content-Disposition: form-data; name="field.authenticatorPlugins" - ... - ... Z3JvdXBz - ... -----------------------------2026736768606413562109112352-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 200 Ok ... @@ -465,168 +259,87 @@ Next we'll select the credentials and authenticators for the PAU: Now, we can define some groups. Let's start with a group named "Admin": - >>> print(http(r""" - ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.title', 'Admin'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'admin')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 550 - ... Content-Type: multipart/form-data; boundary=---------------------------20619400354342370301249668954 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/groups/+/AddGroupInformation.html= ... - ... -----------------------------20619400354342370301249668954 - ... Content-Disposition: form-data; name="field.title" - ... - ... Admin - ... -----------------------------20619400354342370301249668954 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------20619400354342370301249668954 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------20619400354342370301249668954 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... admin - ... -----------------------------20619400354342370301249668954-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... That includes Betty, Mary and Mike: - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.title', 'Admin'), + ... ('field.description', ''), + ... ('field.principals.displayed', 'y'), + ... ('field.principals.MC51c2Vycw__.query.field.search', ''), + ... ('field.principals:list', 'dXNlcnMz'), + ... ('field.principals:list', 'dXNlcnM3'), + ... ('field.principals:list', 'dXNlcnM2'), + ... ('field.principals.MC51c2Vycw__.apply', 'Apply'), + ... ('field.principals.MC5ncm91cHM_.query.field.search', ''), + ... ('field.principals.users6.query.field.search', ''), + ... ('field.principals.MQ__.query.searchstring', 'Apply')]) + >>> print(http(b""" ... POST /++etc++site/default/PAU/groups/admin/@@edit.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 1509 - ... Content-Type: multipart/form-data; boundary=---------------------------6981402699601872602121555350 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/groups/admin/@@edit.html ... - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.title" - ... - ... Admin - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals.displayed" - ... - ... y - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals.MC51c2Vycw__.query.field.search" - ... - ... - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals:list" - ... - ... dXNlcnMz - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals:list" - ... - ... dXNlcnM3 - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals:list" - ... - ... dXNlcnM2 - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals.MC51c2Vycw__.apply" - ... - ... Apply - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals.MC5ncm91cHM_.query.field.search" - ... - ... - ... -----------------------------6981402699601872602121555350 - ... Content-Disposition: form-data; name="field.principals.MQ__.query.searchstring" - ... - ... - ... -----------------------------6981402699601872602121555350-- - ... """)) + ... %b + ... """ % (content_type, content), handle_errors=False)) HTTP/1.1 200 Ok ... and a group "Power Users" - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.title', 'Power Users'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'power')]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 561 - ... Content-Type: multipart/form-data; boundary=---------------------------168380148515549442351132560943 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/groups/+/AddGroupInformation.html= ... - ... -----------------------------168380148515549442351132560943 - ... Content-Disposition: form-data; name="field.title" - ... - ... Power Users - ... -----------------------------168380148515549442351132560943 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------168380148515549442351132560943 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------168380148515549442351132560943 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... power - ... -----------------------------168380148515549442351132560943-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... with Bill and Betty as members: - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.title', 'Power Users'), + ... ('field.description', ''), + ... ('field.principals:list', 'dXNlcnMz'), + ... ('field.principals:list', 'dXNlcnMy'), + ... ('field.principals.displayed', 'y'), + ... ('field.principals.MC51c2Vycw__.query.field.search', ''), + ... ('field.principals.MC5ncm91cHM_.query.field.search', ''), + ... ('field.principals.MQ__.query.searchstring', ''), + ... ('UPDATE_SUBMIT', 'Change')]) + >>> print(http(b""" ... POST /++etc++site/default/PAU/groups/power/@@edit.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 1729 - ... Content-Type: multipart/form-data; boundary=---------------------------181944013812647128322134918391 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/groups/power/@@edit.html ... - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.title" - ... - ... Power Users - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.principals:list" - ... - ... dXNlcnMz - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.principals:list" - ... - ... dXNlcnMy - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.principals.displayed" - ... - ... y - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.principals.MC51c2Vycw__.query.field.search" - ... - ... - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.principals.MC5ncm91cHM_.query.field.search" - ... - ... - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="field.principals.MQ__.query.searchstring" - ... - ... - ... -----------------------------181944013812647128322134918391 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Change - ... -----------------------------181944013812647128322134918391-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 200 Ok ... diff --git a/src/zope/app/authentication/browser/tests/test_doctests.py b/src/zope/app/authentication/browser/tests/test_doctests.py index 2723b3a..eda9690 100644 --- a/src/zope/app/authentication/browser/tests/test_doctests.py +++ b/src/zope/app/authentication/browser/tests/test_doctests.py @@ -20,6 +20,7 @@ import doctest import re import unittest +import webtest import transaction from webtest import TestApp @@ -33,7 +34,7 @@ from zope.app.authentication.principalfolder import PrincipalFolder from zope.app.authentication.testing import AppAuthenticationLayer - +TEST_APP_FOR_ENCODING = webtest.TestApp(None) class FunkTest(unittest.TestCase): layer = AppAuthenticationLayer @@ -133,6 +134,13 @@ def test_cutpaste_duplicated_id_object(self): (re.compile(r"u'([^']*)'"), r"'\1'"), ]) +def encodeMultipartFormdata(fields: list[tuple[str, str]], files: list | None = None) -> tuple[bytes, bytes]: + if files is None: + files = [] + content_type, content = TEST_APP_FOR_ENCODING.encode_multipart( + fields, files) + return content_type.encode(), content + def test_suite(): flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS @@ -153,6 +161,7 @@ def make_doctest(path): optionflags=flags, globs={ 'http': _http, + 'encodeMultipartFormdata': encodeMultipartFormdata, 'getRootFolder': AppAuthenticationLayer.getRootFolder }) test.layer = AppAuthenticationLayer From 11cd2dee8e3e5200e1105cc3a18b2028bf343b05 Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Fri, 22 Nov 2024 09:29:48 +0100 Subject: [PATCH 2/5] Fix another test + make code usable on older Python versions. --- .../browser/pau_prefix_and_searching.rst | 234 ++++++------------ .../browser/tests/test_doctests.py | 6 +- 2 files changed, 81 insertions(+), 159 deletions(-) diff --git a/src/zope/app/authentication/browser/pau_prefix_and_searching.rst b/src/zope/app/authentication/browser/pau_prefix_and_searching.rst index 38917f8..b7e1ea4 100644 --- a/src/zope/app/authentication/browser/pau_prefix_and_searching.rst +++ b/src/zope/app/authentication/browser/pau_prefix_and_searching.rst @@ -7,165 +7,105 @@ PAUs that have prefixes. First we'll create a PAU with a prefix of `pau1_` and and register: - >>> print(http(r""" - ... POST /++etc++site/default/+/AddPluggableAuthentication.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.prefix', 'pau1_'), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'PAU1'), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/+/AddPluggableAuthentication.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 372 - ... Content-Type: multipart/form-data; boundary=---------------------------318183180122653 - ... - ... -----------------------------318183180122653 - ... Content-Disposition: form-data; name="field.prefix" - ... - ... pau1_ - ... -----------------------------318183180122653 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" + ... Content-Type: %b ... - ... Add - ... -----------------------------318183180122653 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... PAU1 - ... -----------------------------318183180122653-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.comment', ''), + ... ('field.actions.register', 'Register'), + ... ]) + >>> print(http(b""" ... POST /++etc++site/default/PAU1/addRegistration.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 591 - ... Content-Type: multipart/form-data; boundary=---------------------------516441125097 - ... - ... -----------------------------516441125097 - ... Content-Disposition: form-data; name="field.comment" + ... Content-Type: %b ... - ... - ... -----------------------------516441125097 - ... Content-Disposition: form-data; name="field.actions.register" - ... - ... Register - ... -----------------------------516441125097-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... Next we'll create and register a principal folder: - >>> print(http(r""" - ... POST /++etc++site/default/PAU1/+/AddPrincipalFolder.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.prefix', 'users_'), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'Users'), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU1/+/AddPrincipalFolder.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 374 - ... Content-Type: multipart/form-data; boundary=---------------------------266241536215161 - ... - ... -----------------------------266241536215161 - ... Content-Disposition: form-data; name="field.prefix" - ... - ... users_ - ... -----------------------------266241536215161 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" + ... Content-Type: %b ... - ... Add - ... -----------------------------266241536215161 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... Users - ... -----------------------------266241536215161-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... and add a principal that we'll later search for: - >>> print(http(r""" - ... POST /++etc++site/default/PAU1/Users/+/AddPrincipalInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.login', 'bob'), + ... ('field.passwordManagerName', 'Plain Text'), + ... ('field.password', 'bob'), + ... ('field.title', 'Bob'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', ''), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU1/Users/+/AddPrincipalInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 686 - ... Content-Type: multipart/form-data; boundary=---------------------------300171485226567 - ... - ... -----------------------------300171485226567 - ... Content-Disposition: form-data; name="field.login" - ... - ... bob - ... -----------------------------300171485226567 - ... Content-Disposition: form-data; name="field.passwordManagerName" - ... - ... Plain Text - ... -----------------------------300171485226567 - ... Content-Disposition: form-data; name="field.password" - ... - ... bob - ... -----------------------------300171485226567 - ... Content-Disposition: form-data; name="field.title" - ... - ... Bob - ... -----------------------------300171485226567 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------300171485226567 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------300171485226567 - ... Content-Disposition: form-data; name="add_input_name" + ... Content-Type: %b ... - ... - ... -----------------------------300171485226567-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... Next, we'll add and register a group folder: - >>> print(http(r""" - ... POST /++etc++site/default/PAU1/+/AddGroupFolder.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.prefix', 'groups_'), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'Groups'), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU1/+/AddGroupFolder.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 372 - ... Content-Type: multipart/form-data; boundary=---------------------------17420126702455 - ... - ... -----------------------------17420126702455 - ... Content-Disposition: form-data; name="field.prefix" + ... Content-Type: %b ... - ... groups_ - ... -----------------------------17420126702455 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------17420126702455 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... Groups - ... -----------------------------17420126702455-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... and add a group to search for: - >>> print(http(r""" - ... POST /++etc++site/default/PAU1/Groups/+/AddGroupInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.title', 'Nice People'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'nice'), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU1/Groups/+/AddGroupInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 485 - ... Content-Type: multipart/form-data; boundary=---------------------------323081358415654 - ... - ... -----------------------------323081358415654 - ... Content-Disposition: form-data; name="field.title" - ... - ... Nice People - ... -----------------------------323081358415654 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------323081358415654 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------323081358415654 - ... Content-Disposition: form-data; name="add_input_name" + ... Content-Type: %b ... - ... nice - ... -----------------------------323081358415654-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... @@ -175,42 +115,22 @@ group. Before we search, we need to register the two authenticator plugins with the PAU: - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.credentialsPlugins-empty-marker', ''), + ... ('field.authenticatorPlugins.to', 'R3JvdXBz'), + ... ('field.authenticatorPlugins.to', 'VXNlcnM='), + ... ('field.authenticatorPlugins-empty-marker', ''), + ... ('UPDATE_SUBMIT', 'Change'), + ... ('field.authenticatorPlugins', 'R3JvdXBz'), + ... ('field.authenticatorPlugins', 'VXNlcnM='), + ... ]) + >>> print(http(b""" ... POST /++etc++site/default/PAU1/@@configure.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 888 - ... Content-Type: multipart/form-data; boundary=---------------------------610310492754 - ... - ... -----------------------------610310492754 - ... Content-Disposition: form-data; name="field.credentialsPlugins-empty-marker" - ... - ... - ... -----------------------------610310492754 - ... Content-Disposition: form-data; name="field.authenticatorPlugins.to" - ... - ... R3JvdXBz - ... -----------------------------610310492754 - ... Content-Disposition: form-data; name="field.authenticatorPlugins.to" - ... - ... VXNlcnM= - ... -----------------------------610310492754 - ... Content-Disposition: form-data; name="field.authenticatorPlugins-empty-marker" - ... - ... - ... -----------------------------610310492754 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Change - ... -----------------------------610310492754 - ... Content-Disposition: form-data; name="field.authenticatorPlugins" - ... - ... R3JvdXBz - ... -----------------------------610310492754 - ... Content-Disposition: form-data; name="field.authenticatorPlugins" + ... Content-Type: %b ... - ... VXNlcnM= - ... -----------------------------610310492754-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 200 Ok ... @@ -220,7 +140,6 @@ the available groups: >>> print(http(r""" ... POST /@@grant.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 191 ... Content-Type: application/x-www-form-urlencoded ... ... field.principal.displayed=y&""" @@ -244,7 +163,6 @@ principals: >>> print(http(r""" ... POST /@@grant.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 255 ... Content-Type: application/x-www-form-urlencoded ... ... field.principal.displayed=y&""" diff --git a/src/zope/app/authentication/browser/tests/test_doctests.py b/src/zope/app/authentication/browser/tests/test_doctests.py index eda9690..54c317a 100644 --- a/src/zope/app/authentication/browser/tests/test_doctests.py +++ b/src/zope/app/authentication/browser/tests/test_doctests.py @@ -19,6 +19,7 @@ import doctest import re +import typing import unittest import webtest @@ -134,7 +135,10 @@ def test_cutpaste_duplicated_id_object(self): (re.compile(r"u'([^']*)'"), r"'\1'"), ]) -def encodeMultipartFormdata(fields: list[tuple[str, str]], files: list | None = None) -> tuple[bytes, bytes]: + +def encodeMultipartFormdata( + fields: typing.List[typing.Tuple[str, str]], + files: typing.Optional[list] = None) -> typing.Tuple[bytes, bytes]: if files is None: files = [] content_type, content = TEST_APP_FOR_ENCODING.encode_multipart( From 4be235d561af9ee237ecafdd670883b647ef106a Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Wed, 27 Nov 2024 09:39:20 +0100 Subject: [PATCH 3/5] Fix last of the tests. --- .../group_searching_with_empty_string.rst | 166 ++++++------------ .../browser/tests/test_doctests.py | 5 +- 2 files changed, 57 insertions(+), 114 deletions(-) diff --git a/src/zope/app/authentication/browser/group_searching_with_empty_string.rst b/src/zope/app/authentication/browser/group_searching_with_empty_string.rst index 665eb7e..e932685 100644 --- a/src/zope/app/authentication/browser/group_searching_with_empty_string.rst +++ b/src/zope/app/authentication/browser/group_searching_with_empty_string.rst @@ -6,7 +6,6 @@ We'll add a pluggable authentication utility: >>> print(http(r""" ... POST /++etc++site/default/@@contents.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 98 ... Content-Type: application/x-www-form-urlencoded ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication ... @@ -17,111 +16,74 @@ We'll add a pluggable authentication utility: And register it: - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.comment', ''), + ... ('field.actions.register', 'Register'), + ... ]) + >>> print(http(b""" ... POST /++etc++site/default/PAU/addRegistration.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 699 - ... Content-Type: multipart/form-data; boundary=---------------------------191720529414243436931796477300 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/addRegistration.html ... - ... -----------------------------191720529414243436931796477300 - ... Content-Disposition: form-data; name="field.comment" - ... - ... - ... -----------------------------191720529414243436931796477300 - ... Content-Disposition: form-data; name="field.actions.register" - ... - ... Register - ... -----------------------------191720529414243436931796477300-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... Next, we'll add the group folder: - >>> print(http(r""" - ... POST /++etc++site/default/PAU/+/AddGroupFolder.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.prefix', 'groups'), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'groups'), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/+/AddGroupFolder.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 427 - ... Content-Type: multipart/form-data; boundary=---------------------------4150524541658557772058105275 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/+/AddGroupFolder.html= ... - ... -----------------------------4150524541658557772058105275 - ... Content-Disposition: form-data; name="field.prefix" - ... - ... groups - ... -----------------------------4150524541658557772058105275 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------4150524541658557772058105275 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... groups - ... -----------------------------4150524541658557772058105275-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... And add some groups: - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.title', 'Test1'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'Test1'), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 550 - ... Content-Type: multipart/form-data; boundary=---------------------------12719796373012316301953477158 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/groups/+/AddGroupInformation.html= ... - ... -----------------------------12719796373012316301953477158 - ... Content-Disposition: form-data; name="field.title" - ... - ... Test1 - ... -----------------------------12719796373012316301953477158 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------12719796373012316301953477158 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------12719796373012316301953477158 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... Test1 - ... -----------------------------12719796373012316301953477158-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... - - >>> print(http(r""" - ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%3D HTTP/1.1 + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.title', 'Test2'), + ... ('field.description', ''), + ... ('UPDATE_SUBMIT', 'Add'), + ... ('add_input_name', 'Test2'), + ... ]) + >>> print(http(b""" + ... POST /++etc++site/default/PAU/groups/+/AddGroupInformation.html%%3D HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 550 - ... Content-Type: multipart/form-data; boundary=---------------------------10816732208483809451400699513 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/groups/+/AddGroupInformation.html= ... - ... -----------------------------10816732208483809451400699513 - ... Content-Disposition: form-data; name="field.title" - ... - ... Test2 - ... -----------------------------10816732208483809451400699513 - ... Content-Disposition: form-data; name="field.description" - ... - ... - ... -----------------------------10816732208483809451400699513 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Add - ... -----------------------------10816732208483809451400699513 - ... Content-Disposition: form-data; name="add_input_name" - ... - ... Test2 - ... -----------------------------10816732208483809451400699513-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 303 See Other ... @@ -129,44 +91,23 @@ And add some groups: Now we'll configure our pluggable-authentication utility to use the group folder: - - >>> print(http(r""" + >>> content_type, content = encodeMultipartFormdata([ + ... ('field.credentialsPlugins.to', 'U2Vzc2lvbiBDcmVkZW50aWFscw=='), + ... ('field.credentialsPlugins-empty-marker', ''), + ... ('field.authenticatorPlugins.to', 'Z3JvdXBz'), + ... ('field.authenticatorPlugins-empty-marker', ''), + ... ('UPDATE_SUBMIT', 'Change'), + ... ('field.credentialsPlugins', 'U2Vzc2lvbiBDcmVkZW50aWFscw=='), + ... ('field.authenticatorPlugins', 'Z3JvdXBz'), + ... ]) + >>> print(http(b""" ... POST /++etc++site/default/PAU/@@configure.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 1040 - ... Content-Type: multipart/form-data; boundary=---------------------------1786480431902757372789659730 + ... Content-Type: %b ... Referer: http://localhost/++etc++site/default/PAU/@@configure.html ... - ... -----------------------------1786480431902757372789659730 - ... Content-Disposition: form-data; name="field.credentialsPlugins.to" - ... - ... U2Vzc2lvbiBDcmVkZW50aWFscw== - ... -----------------------------1786480431902757372789659730 - ... Content-Disposition: form-data; name="field.credentialsPlugins-empty-marker" - ... - ... - ... -----------------------------1786480431902757372789659730 - ... Content-Disposition: form-data; name="field.authenticatorPlugins.to" - ... - ... Z3JvdXBz - ... -----------------------------1786480431902757372789659730 - ... Content-Disposition: form-data; name="field.authenticatorPlugins-empty-marker" - ... - ... - ... -----------------------------1786480431902757372789659730 - ... Content-Disposition: form-data; name="UPDATE_SUBMIT" - ... - ... Change - ... -----------------------------1786480431902757372789659730 - ... Content-Disposition: form-data; name="field.credentialsPlugins" - ... - ... U2Vzc2lvbiBDcmVkZW50aWFscw== - ... -----------------------------1786480431902757372789659730 - ... Content-Disposition: form-data; name="field.authenticatorPlugins" - ... - ... Z3JvdXBz - ... -----------------------------1786480431902757372789659730-- - ... """)) + ... %b + ... """ % (content_type, content))) HTTP/1.1 200 Ok ... @@ -176,7 +117,6 @@ Now, if we search for a group, but don't supply a string: >>> print(http(r""" ... POST /@@grant.html HTTP/1.1 ... Authorization: Basic bWdyOm1ncnB3 - ... Content-Length: 166 ... Content-Type: application/x-www-form-urlencoded ... Referer: http://localhost/@@grant.html ... diff --git a/src/zope/app/authentication/browser/tests/test_doctests.py b/src/zope/app/authentication/browser/tests/test_doctests.py index 54c317a..978e23a 100644 --- a/src/zope/app/authentication/browser/tests/test_doctests.py +++ b/src/zope/app/authentication/browser/tests/test_doctests.py @@ -21,9 +21,9 @@ import re import typing import unittest -import webtest import transaction +import webtest from webtest import TestApp from zope.app.wsgi.testlayer import http from zope.exceptions.interfaces import UserError @@ -35,7 +35,10 @@ from zope.app.authentication.principalfolder import PrincipalFolder from zope.app.authentication.testing import AppAuthenticationLayer + TEST_APP_FOR_ENCODING = webtest.TestApp(None) + + class FunkTest(unittest.TestCase): layer = AppAuthenticationLayer From 47863362fe3a11e5ba584cbbe81ce5f283cf1d7d Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Thu, 28 Nov 2024 08:44:39 +0100 Subject: [PATCH 4/5] Use function moved to zope.app.wsgi. --- setup.py | 2 +- .../browser/tests/test_doctests.py | 16 +--------------- tox.ini | 1 + 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/setup.py b/setup.py index 9fbb4f6..7d1ee56 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ def read(*rnames): 'zope.app.rotterdam >= 4.0', 'zope.app.basicskin >= 4.0', 'zope.app.form >= 5.0', - 'zope.app.wsgi', + 'zope.app.wsgi >= 5.3.dev0', 'zope.app.schema', 'zope.formlib', diff --git a/src/zope/app/authentication/browser/tests/test_doctests.py b/src/zope/app/authentication/browser/tests/test_doctests.py index 978e23a..79bee2b 100644 --- a/src/zope/app/authentication/browser/tests/test_doctests.py +++ b/src/zope/app/authentication/browser/tests/test_doctests.py @@ -19,12 +19,11 @@ import doctest import re -import typing import unittest import transaction -import webtest from webtest import TestApp +from zope.app.wsgi.testlayer import encodeMultipartFormdata from zope.app.wsgi.testlayer import http from zope.exceptions.interfaces import UserError from zope.interface import directlyProvides @@ -36,9 +35,6 @@ from zope.app.authentication.testing import AppAuthenticationLayer -TEST_APP_FOR_ENCODING = webtest.TestApp(None) - - class FunkTest(unittest.TestCase): layer = AppAuthenticationLayer @@ -139,16 +135,6 @@ def test_cutpaste_duplicated_id_object(self): ]) -def encodeMultipartFormdata( - fields: typing.List[typing.Tuple[str, str]], - files: typing.Optional[list] = None) -> typing.Tuple[bytes, bytes]: - if files is None: - files = [] - content_type, content = TEST_APP_FOR_ENCODING.encode_multipart( - fields, files) - return content_type.encode(), content - - def test_suite(): flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS diff --git a/tox.ini b/tox.ini index dcfd08e..8f8f0e5 100644 --- a/tox.ini +++ b/tox.ini @@ -15,6 +15,7 @@ envlist = [testenv] usedevelop = true deps = + git+https://github.com/zopefoundation/zope.app.wsgi.git@encodeMultipartFormdata#egg=zope.app.wsgi commands = zope-testrunner --test-path=src {posargs:-vc} extras = From 8e8f918a2c14fd36f3bd9a32baeb0a7a4ccd7bc2 Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Fri, 29 Nov 2024 07:59:55 +0100 Subject: [PATCH 5/5] Depend on released version of zope.app.wsgi. --- setup.py | 2 +- tox.ini | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 7d1ee56..5f75691 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ def read(*rnames): 'zope.app.rotterdam >= 4.0', 'zope.app.basicskin >= 4.0', 'zope.app.form >= 5.0', - 'zope.app.wsgi >= 5.3.dev0', + 'zope.app.wsgi[testlayer] >= 5.3', 'zope.app.schema', 'zope.formlib', diff --git a/tox.ini b/tox.ini index 8f8f0e5..dcfd08e 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,6 @@ envlist = [testenv] usedevelop = true deps = - git+https://github.com/zopefoundation/zope.app.wsgi.git@encodeMultipartFormdata#egg=zope.app.wsgi commands = zope-testrunner --test-path=src {posargs:-vc} extras =