| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | __filename__ = "tests.py" | 
					
						
							|  |  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2021-01-26 10:07:42 +00:00
										 |  |  |  | __version__ = "1.2.0" | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  |  | __email__ = "bob@freedombone.net" | 
					
						
							|  |  |  |  | __status__ = "Production" | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | import time | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | import os | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | import shutil | 
					
						
							| 
									
										
										
										
											2019-08-16 10:36:41 +00:00
										 |  |  |  | import json | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2021-05-10 13:43:38 +00:00
										 |  |  |  | from random import randint | 
					
						
							| 
									
										
										
										
											2019-08-15 18:21:43 +00:00
										 |  |  |  | from time import gmtime, strftime | 
					
						
							| 
									
										
										
										
											2019-07-09 14:20:23 +00:00
										 |  |  |  | from pprint import pprint | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | from httpsig import signPostHeaders | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  | from httpsig import signPostHeadersNew | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | from httpsig import verifyPostHeaders | 
					
						
							| 
									
										
										
										
											2019-08-17 10:15:01 +00:00
										 |  |  |  | from httpsig import messageContentDigest | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | from cache import storePersonInCache | 
					
						
							|  |  |  |  | from cache import getPersonFromCache | 
					
						
							|  |  |  |  | from threads import threadWithTrace | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | from daemon import runDaemon | 
					
						
							|  |  |  |  | from session import createSession | 
					
						
							| 
									
										
										
										
											2021-04-30 11:45:46 +00:00
										 |  |  |  | from posts import removePostInteractions | 
					
						
							| 
									
										
										
										
											2020-12-13 19:05:26 +00:00
										 |  |  |  | from posts import getMentionedPeople | 
					
						
							| 
									
										
										
										
											2020-08-25 19:35:55 +00:00
										 |  |  |  | from posts import validContentWarning | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | from posts import deleteAllPosts | 
					
						
							|  |  |  |  | from posts import createPublicPost | 
					
						
							| 
									
										
										
										
											2019-06-30 22:56:37 +00:00
										 |  |  |  | from posts import sendPost | 
					
						
							| 
									
										
										
										
											2019-07-05 14:39:24 +00:00
										 |  |  |  | from posts import noOfFollowersOnDomain | 
					
						
							| 
									
										
										
										
											2019-07-08 08:51:33 +00:00
										 |  |  |  | from posts import groupFollowersByDomain | 
					
						
							| 
									
										
										
										
											2019-07-12 22:29:10 +00:00
										 |  |  |  | from posts import archivePostsForPerson | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | from posts import sendPostViaServer | 
					
						
							| 
									
										
										
										
											2019-07-01 11:09:09 +00:00
										 |  |  |  | from follow import clearFollows | 
					
						
							|  |  |  |  | from follow import clearFollowers | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |  | from follow import sendFollowRequestViaServer | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |  | from follow import sendUnfollowRequestViaServer | 
					
						
							| 
									
										
										
										
											2021-03-03 20:34:55 +00:00
										 |  |  |  | from utils import camelCaseSplit | 
					
						
							| 
									
										
										
										
											2021-01-25 12:24:40 +00:00
										 |  |  |  | from utils import decodedHost | 
					
						
							| 
									
										
										
										
											2020-12-16 11:19:16 +00:00
										 |  |  |  | from utils import getFullDomain | 
					
						
							| 
									
										
										
										
											2020-11-24 10:53:10 +00:00
										 |  |  |  | from utils import validNickname | 
					
						
							| 
									
										
										
										
											2020-11-08 11:24:43 +00:00
										 |  |  |  | from utils import firstParagraphFromString | 
					
						
							| 
									
										
										
										
											2020-08-23 11:13:35 +00:00
										 |  |  |  | from utils import removeIdEnding | 
					
						
							| 
									
										
										
										
											2021-02-10 11:24:34 +00:00
										 |  |  |  | from siteactive import siteIsActive | 
					
						
							| 
									
										
										
										
											2019-11-24 17:40:31 +00:00
										 |  |  |  | from utils import updateRecentPostsCache | 
					
						
							| 
									
										
										
										
											2019-07-06 19:24:52 +00:00
										 |  |  |  | from utils import followPerson | 
					
						
							| 
									
										
										
										
											2019-08-21 16:35:46 +00:00
										 |  |  |  | from utils import getNicknameFromActor | 
					
						
							|  |  |  |  | from utils import getDomainFromActor | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  | from utils import copytree | 
					
						
							| 
									
										
										
										
											2019-11-23 10:08:00 +00:00
										 |  |  |  | from utils import loadJson | 
					
						
							|  |  |  |  | from utils import saveJson | 
					
						
							| 
									
										
										
										
											2019-10-12 12:45:53 +00:00
										 |  |  |  | from utils import getStatusNumber | 
					
						
							| 
									
										
										
										
											2020-09-25 13:21:56 +00:00
										 |  |  |  | from utils import getFollowersOfPerson | 
					
						
							| 
									
										
										
										
											2020-10-25 12:47:16 +00:00
										 |  |  |  | from utils import removeHtml | 
					
						
							| 
									
										
										
										
											2021-01-31 11:05:17 +00:00
										 |  |  |  | from utils import dangerousMarkup | 
					
						
							| 
									
										
										
										
											2021-03-12 12:04:34 +00:00
										 |  |  |  | from pgp import extractPGPPublicKey | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |  | from pgp import pgpPublicKeyUpload | 
					
						
							| 
									
										
										
										
											2021-03-12 12:04:34 +00:00
										 |  |  |  | from utils import containsPGPPublicKey | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | from follow import followerOfPerson | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  | from follow import unfollowAccount | 
					
						
							|  |  |  |  | from follow import unfollowerOfAccount | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |  | from follow import sendFollowRequest | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  | from person import createPerson | 
					
						
							| 
									
										
										
										
											2019-08-22 18:36:07 +00:00
										 |  |  |  | from person import setDisplayNickname | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  | from person import setBio | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  | # from person import generateRSAKey | 
					
						
							| 
									
										
										
										
											2019-07-19 10:01:24 +00:00
										 |  |  |  | from skills import setSkillLevel | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  | from skills import actorSkillValue | 
					
						
							| 
									
										
										
										
											2021-05-13 14:13:27 +00:00
										 |  |  |  | from skills import setSkillsFromDict | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  | from skills import actorHasSkill | 
					
						
							| 
									
										
										
										
											2021-05-13 19:58:16 +00:00
										 |  |  |  | from roles import setRolesFromList | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |  | from roles import setRole | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  | from roles import actorHasRole | 
					
						
							| 
									
										
										
										
											2020-09-03 18:48:32 +00:00
										 |  |  |  | from auth import constantTimeStringCheck | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  | from auth import createBasicAuthHeader | 
					
						
							|  |  |  |  | from auth import authorizeBasic | 
					
						
							|  |  |  |  | from auth import storeBasicCredentials | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |  | from like import likePost | 
					
						
							| 
									
										
										
										
											2019-07-18 09:26:47 +00:00
										 |  |  |  | from like import sendLikeViaServer | 
					
						
							| 
									
										
										
										
											2019-07-11 17:55:10 +00:00
										 |  |  |  | from announce import announcePublic | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |  | from announce import sendAnnounceViaServer | 
					
						
							| 
									
										
										
										
											2021-05-10 18:53:20 +00:00
										 |  |  |  | from city import spoofGeolocation | 
					
						
							| 
									
										
										
										
											2019-07-12 19:26:54 +00:00
										 |  |  |  | from media import getMediaPath | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |  | from media import getAttachmentMediaType | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |  | from delete import sendDeleteViaServer | 
					
						
							| 
									
										
										
										
											2020-08-21 18:32:16 +00:00
										 |  |  |  | from inbox import jsonPostAllowsComments | 
					
						
							| 
									
										
										
										
											2019-07-18 09:26:47 +00:00
										 |  |  |  | from inbox import validInbox | 
					
						
							| 
									
										
										
										
											2019-07-18 11:35:48 +00:00
										 |  |  |  | from inbox import validInboxFilenames | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  | from categories import guessHashtagCategory | 
					
						
							| 
									
										
										
										
											2021-03-01 10:02:55 +00:00
										 |  |  |  | from content import extractTextFieldsInPOST | 
					
						
							| 
									
										
										
										
											2021-02-09 13:28:42 +00:00
										 |  |  |  | from content import validHashTag | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  | from content import htmlReplaceEmailQuote | 
					
						
							| 
									
										
										
										
											2020-08-02 17:01:12 +00:00
										 |  |  |  | from content import htmlReplaceQuoteMarks | 
					
						
							| 
									
										
										
										
											2020-12-13 14:48:45 +00:00
										 |  |  |  | from content import dangerousCSS | 
					
						
							| 
									
										
										
										
											2019-09-01 08:55:05 +00:00
										 |  |  |  | from content import addWebLinks | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  | from content import replaceEmojiFromTags | 
					
						
							|  |  |  |  | from content import addHtmlTags | 
					
						
							| 
									
										
										
										
											2019-11-04 20:39:14 +00:00
										 |  |  |  | from content import removeLongWords | 
					
						
							| 
									
										
										
										
											2020-05-12 09:34:58 +00:00
										 |  |  |  | from content import replaceContentDuplicates | 
					
						
							| 
									
										
										
										
											2020-06-14 13:25:38 +00:00
										 |  |  |  | from content import removeTextFormatting | 
					
						
							| 
									
										
										
										
											2020-10-11 09:33:31 +00:00
										 |  |  |  | from content import removeHtmlTag | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |  | from theme import setCSSparam | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  | from linked_data_sig import generateJsonSignature | 
					
						
							|  |  |  |  | from linked_data_sig import verifyJsonSignature | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | from newsdaemon import hashtagRuleTree | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  | from newsdaemon import hashtagRuleResolve | 
					
						
							| 
									
										
										
										
											2020-10-25 10:06:54 +00:00
										 |  |  |  | from newswire import getNewswireTags | 
					
						
							| 
									
										
										
										
											2020-11-22 18:43:01 +00:00
										 |  |  |  | from newswire import parseFeedDate | 
					
						
							| 
									
										
										
										
											2021-01-22 13:32:37 +00:00
										 |  |  |  | from mastoapiv1 import getMastoApiV1IdFromNickname | 
					
						
							|  |  |  |  | from mastoapiv1 import getNicknameFromMastoApiV1Id | 
					
						
							| 
									
										
										
										
											2021-02-02 21:08:33 +00:00
										 |  |  |  | from webapp_post import prepareHtmlPostNickname | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  | from webapp_utils import markdownToHtml | 
					
						
							| 
									
										
										
										
											2021-03-01 21:46:44 +00:00
										 |  |  |  | from speaker import speakerReplaceLinks | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | testServerAliceRunning = False | 
					
						
							|  |  |  |  | testServerBobRunning = False | 
					
						
							|  |  |  |  | testServerEveRunning = False | 
					
						
							|  |  |  |  | thrAlice = None | 
					
						
							|  |  |  |  | thrBob = None | 
					
						
							|  |  |  |  | thrEve = None | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 21:27:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  | def testHttpSigNew(): | 
					
						
							|  |  |  |  |     print('testHttpSigNew') | 
					
						
							|  |  |  |  |     messageBodyJson = {"hello": "world"} | 
					
						
							|  |  |  |  |     messageBodyJsonStr = json.dumps(messageBodyJson) | 
					
						
							|  |  |  |  |     publicKeyPem = \ | 
					
						
							|  |  |  |  |         '-----BEGIN RSA PUBLIC KEY-----\n' + \ | 
					
						
							|  |  |  |  |         'MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8' + \ | 
					
						
							|  |  |  |  |         'cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw\n' + \ | 
					
						
							|  |  |  |  |         'WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajz' + \ | 
					
						
							|  |  |  |  |         'rw3MOEt8uA5txSKobBpKDeBLOsdJKFq\n' + \ | 
					
						
							|  |  |  |  |         'MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd' + \ | 
					
						
							|  |  |  |  |         '/QBwVW9OwNFhekro3RtlinV0a75jfZg\n' + \ | 
					
						
							|  |  |  |  |         'kne/YiktSvLG34lw2zqXBDTC5NHROUqGT' + \ | 
					
						
							|  |  |  |  |         'lML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P\n' + \ | 
					
						
							|  |  |  |  |         'uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSF' + \ | 
					
						
							|  |  |  |  |         'Fn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ\n' + \ | 
					
						
							|  |  |  |  |         'PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB\n' + \ | 
					
						
							|  |  |  |  |         '-----END RSA PUBLIC KEY-----\n' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |     privateKeyPem = \ | 
					
						
							|  |  |  |  |         '-----BEGIN RSA PRIVATE KEY-----\n' + \ | 
					
						
							|  |  |  |  |         'MIIEqAIBAAKCAQEAhAKYdtoeoy8zcAcR8' + \ | 
					
						
							|  |  |  |  |         '74L8cnZxKzAGwd7v36APp7Pv6Q2jdsP\n' + \ | 
					
						
							|  |  |  |  |         'BRrwWEBnez6d0UDKDwGbc6nxfEXAy5mbh' + \ | 
					
						
							|  |  |  |  |         'gajzrw3MOEt8uA5txSKobBpKDeBLOsd\n' + \ | 
					
						
							|  |  |  |  |         'JKFqMGmXCQvEG7YemcxDTRPxAleIAgYYR' + \ | 
					
						
							|  |  |  |  |         'jTSd/QBwVW9OwNFhekro3RtlinV0a75\n' + \ | 
					
						
							|  |  |  |  |         'jfZgkne/YiktSvLG34lw2zqXBDTC5NHRO' + \ | 
					
						
							|  |  |  |  |         'UqGTlML4PlNZS5Ri2U4aCNx2rUPRcKI\n' + \ | 
					
						
							|  |  |  |  |         'lE0PuKxI4T+HIaFpv8+rdV6eUgOrB2xeI' + \ | 
					
						
							|  |  |  |  |         '1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZ\n' + \ | 
					
						
							|  |  |  |  |         'SFlQPSXSfBDiUGhwOw76WuSSsf1D4b/vL' + \ | 
					
						
							|  |  |  |  |         'oJ10wIDAQABAoIBAG/JZuSWdoVHbi56\n' + \ | 
					
						
							|  |  |  |  |         'vjgCgkjg3lkO1KrO3nrdm6nrgA9P9qaPj' + \ | 
					
						
							|  |  |  |  |         'xuKoWaKO1cBQlE1pSWp/cKncYgD5WxE\n' + \ | 
					
						
							|  |  |  |  |         'CpAnRUXG2pG4zdkzCYzAh1i+c34L6oZoH' + \ | 
					
						
							|  |  |  |  |         'sirK6oNcEnHveydfzJL5934egm6p8DW\n' + \ | 
					
						
							|  |  |  |  |         '+m1RQ70yUt4uRc0YSor+q1LGJvGQHReF0' + \ | 
					
						
							|  |  |  |  |         'WmJBZHrhz5e63Pq7lE0gIwuBqL8SMaA\n' + \ | 
					
						
							|  |  |  |  |         'yRXtK+JGxZpImTq+NHvEWWCu09SCq0r83' + \ | 
					
						
							|  |  |  |  |         '8ceQI55SvzmTkwqtC+8AT2zFviMZkKR\n' + \ | 
					
						
							|  |  |  |  |         'Qo6SPsrqItxZWRty2izawTF0Bf5S2VAx7' + \ | 
					
						
							|  |  |  |  |         'O+6t3wBsQ1sLptoSgX3QblELY5asI0J\n' + \ | 
					
						
							|  |  |  |  |         'YFz7LJECgYkAsqeUJmqXE3LP8tYoIjMIA' + \ | 
					
						
							|  |  |  |  |         'KiTm9o6psPlc8CrLI9CH0UbuaA2JCOM\n' + \ | 
					
						
							|  |  |  |  |         'cCNq8SyYbTqgnWlB9ZfcAm/cFpA8tYci9' + \ | 
					
						
							|  |  |  |  |         'm5vYK8HNxQr+8FS3Qo8N9RJ8d0U5Csw\n' + \ | 
					
						
							|  |  |  |  |         'DzMYfRghAfUGwmlWj5hp1pQzAuhwbOXFt' + \ | 
					
						
							|  |  |  |  |         'xKHVsMPhz1IBtF9Y8jvgqgYHLbmyiu1\n' + \ | 
					
						
							|  |  |  |  |         'mwJ5AL0pYF0G7x81prlARURwHo0Yf52kE' + \ | 
					
						
							|  |  |  |  |         'w1dxpx+JXER7hQRWQki5/NsUEtv+8RT\n' + \ | 
					
						
							|  |  |  |  |         'qn2m6qte5DXLyn83b1qRscSdnCCwKtKWU' + \ | 
					
						
							|  |  |  |  |         'ug5q2ZbwVOCJCtmRwmnP131lWRYfj67\n' + \ | 
					
						
							|  |  |  |  |         'B/xJ1ZA6X3GEf4sNReNAtaucPEelgR2ns' + \ | 
					
						
							|  |  |  |  |         'N0gKQKBiGoqHWbK1qYvBxX2X3kbPDkv\n' + \ | 
					
						
							|  |  |  |  |         '9C+celgZd2PW7aGYLCHq7nPbmfDV0yHcW' + \ | 
					
						
							|  |  |  |  |         'jOhXZ8jRMjmANVR/eLQ2EfsRLdW69bn\n' + \ | 
					
						
							|  |  |  |  |         'f3ZD7JS1fwGnO3exGmHO3HZG+6AvberKY' + \ | 
					
						
							|  |  |  |  |         'VYNHahNFEw5TsAcQWDLRpkGybBcxqZo\n' + \ | 
					
						
							|  |  |  |  |         '81YCqlqidwfeO5YtlO7etx1xLyqa2NsCe' + \ | 
					
						
							|  |  |  |  |         'G9A86UjG+aeNnXEIDk1PDK+EuiThIUa\n' + \ | 
					
						
							|  |  |  |  |         '/2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQ' + \ | 
					
						
							|  |  |  |  |         'YgTImOlfW6/GuYIxKYgEKCFHFqJATAG\n' + \ | 
					
						
							|  |  |  |  |         'IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8Cxa' + \ | 
					
						
							|  |  |  |  |         'EMQoevxAta0ssMK3w6UsDtvUvYvF22m\n' + \ | 
					
						
							|  |  |  |  |         'qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLg' + \ | 
					
						
							|  |  |  |  |         'snrtUPZx+z2Ep2x0xc5orneB5fGyF1P\n' + \ | 
					
						
							|  |  |  |  |         'WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTx' + \ | 
					
						
							|  |  |  |  |         'cjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ\n' + \ | 
					
						
							|  |  |  |  |         'EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRD' + \ | 
					
						
							|  |  |  |  |         's15M38eG2cYwB1PZpDHScDnDA0=\n' + \ | 
					
						
							|  |  |  |  |         '-----END RSA PRIVATE KEY-----' | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  |     sigInput = \ | 
					
						
							|  |  |  |  |         'sig1=(date); alg=rsa-sha256; keyId="test-key-b"' | 
					
						
							|  |  |  |  |     sig = \ | 
					
						
							|  |  |  |  |         'sig1=:HtXycCl97RBVkZi66ADKnC9c5eSSlb57GnQ4KFqNZplOpNfxqk62' + \ | 
					
						
							|  |  |  |  |         'JzZ484jXgLvoOTRaKfR4hwyxlcyb+BWkVasApQovBSdit9Ml/YmN2IvJDPncrlhPD' + \ | 
					
						
							|  |  |  |  |         'VDv36Z9/DiSO+RNHD7iLXugdXo1+MGRimW1RmYdenl/ITeb7rjfLZ4b9VNnLFtVWw' + \ | 
					
						
							|  |  |  |  |         'rjhAiwIqeLjodVImzVc5srrk19HMZNuUejK6I3/MyN3+3U8tIRW4LWzx6ZgGZUaEE' + \ | 
					
						
							|  |  |  |  |         'P0aBlBkt7Fj0Tt5/P5HNW/Sa/m8smxbOHnwzAJDa10PyjzdIbywlnWIIWtZKPPsoV' + \ | 
					
						
							|  |  |  |  |         'oKVopUWEU3TNhpWmaVhFrUL/O6SN3w==:' | 
					
						
							|  |  |  |  |     # "hs2019", using RSASSA-PSS [RFC8017] and SHA-512 [RFC6234] | 
					
						
							|  |  |  |  |     # sigInput = \ | 
					
						
							|  |  |  |  |     #     'sig1=(*request-target, *created, host, date, ' + \ | 
					
						
							|  |  |  |  |     #     'cache-control, x-empty-header, x-example); keyId="test-key-a"; ' + \ | 
					
						
							|  |  |  |  |     #     'alg=hs2019; created=1402170695; expires=1402170995' | 
					
						
							|  |  |  |  |     # sig = \ | 
					
						
							|  |  |  |  |     #  'sig1=:K2qGT5srn2OGbOIDzQ6kYT+ruaycnDAAUpKv+ePFfD0RAxn/1BUe' + \ | 
					
						
							|  |  |  |  |     #  'Zx/Kdrq32DrfakQ6bPsvB9aqZqognNT6be4olHROIkeV879RrsrObury8L9SCEibe' + \ | 
					
						
							|  |  |  |  |     #  'oHyqU/yCjphSmEdd7WD+zrchK57quskKwRefy2iEC5S2uAH0EPyOZKWlvbKmKu5q4' + \ | 
					
						
							|  |  |  |  |     #  'CaB8X/I5/+HLZLGvDiezqi6/7p2Gngf5hwZ0lSdy39vyNMaaAT0tKo6nuVw0S1MVg' + \ | 
					
						
							|  |  |  |  |     #  '1Q7MpWYZs0soHjttq0uLIA3DIbQfLiIvK6/l0BdWTU7+2uQj7lBkQAsFZHoA96ZZg' + \ | 
					
						
							|  |  |  |  |     #  'FquQrXRlmYOh+Hx5D9fJkXcXe5tmAg==:' | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |     nickname = 'foo' | 
					
						
							|  |  |  |  |     boxpath = '/' + nickname | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  |     # headers = { | 
					
						
							|  |  |  |  |     #     "*request-target": "get " + boxpath, | 
					
						
							|  |  |  |  |     #     "*created": "1402170695", | 
					
						
							|  |  |  |  |     #     "host": "example.org", | 
					
						
							|  |  |  |  |     #     "date": "Tue, 07 Jun 2014 20:51:35 GMT", | 
					
						
							|  |  |  |  |     #     "cache-control": "max-age=60, must-revalidate", | 
					
						
							|  |  |  |  |     #     "x-emptyheader": "", | 
					
						
							|  |  |  |  |     #     "x-example": "Example header with some whitespace.", | 
					
						
							|  |  |  |  |     #     "x-dictionary": "b=2", | 
					
						
							|  |  |  |  |     #     "x-dictionary": "a=1", | 
					
						
							|  |  |  |  |     #     "x-list": "(a, b, c)", | 
					
						
							|  |  |  |  |     #     "Signature-Input": sigInput, | 
					
						
							|  |  |  |  |     #     "Signature": sig | 
					
						
							|  |  |  |  |     # } | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |     dateStr = "Tue, 07 Jun 2014 20:51:35 GMT" | 
					
						
							| 
									
										
										
										
											2021-04-04 21:30:26 +00:00
										 |  |  |  |     secondsSinceEpoch = 1402174295 | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |     domain = "example.com" | 
					
						
							|  |  |  |  |     port = 443 | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  |     headers = { | 
					
						
							| 
									
										
										
										
											2021-02-22 18:27:04 +00:00
										 |  |  |  |         "*created": str(secondsSinceEpoch), | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  |         "*request-target": "post /foo?param=value&pet=dog", | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |         "host": domain, | 
					
						
							|  |  |  |  |         "date": dateStr, | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  |         "content-type": "application/json", | 
					
						
							|  |  |  |  |         "digest": "SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=", | 
					
						
							|  |  |  |  |         "content-length": "18", | 
					
						
							|  |  |  |  |         "Signature-Input": sigInput, | 
					
						
							|  |  |  |  |         "Signature": sig | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     debug = False | 
					
						
							|  |  |  |  |     assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, | 
					
						
							|  |  |  |  |                              boxpath, False, None, | 
					
						
							| 
									
										
										
										
											2021-04-04 21:30:26 +00:00
										 |  |  |  |                              messageBodyJsonStr, debug, True) | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |     # make a deliberate mistake | 
					
						
							|  |  |  |  |     headers['Signature'] = headers['Signature'].replace('V', 'B') | 
					
						
							|  |  |  |  |     assert not verifyPostHeaders(httpPrefix, publicKeyPem, headers, | 
					
						
							|  |  |  |  |                                  boxpath, False, None, | 
					
						
							| 
									
										
										
										
											2021-04-04 21:30:26 +00:00
										 |  |  |  |                                  messageBodyJsonStr, debug, True) | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |     # test signing | 
					
						
							|  |  |  |  |     bodyDigest = messageContentDigest(messageBodyJsonStr) | 
					
						
							|  |  |  |  |     contentLength = len(messageBodyJsonStr) | 
					
						
							|  |  |  |  |     headers = { | 
					
						
							|  |  |  |  |         "host": domain, | 
					
						
							|  |  |  |  |         "date": dateStr, | 
					
						
							|  |  |  |  |         "digest": f'SHA-256={bodyDigest}', | 
					
						
							|  |  |  |  |         "content-type": "application/json", | 
					
						
							|  |  |  |  |         "content-length": str(contentLength) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     signatureIndexHeader, signatureHeader = \ | 
					
						
							|  |  |  |  |         signPostHeadersNew(dateStr, privateKeyPem, nickname, | 
					
						
							|  |  |  |  |                            domain, port, | 
					
						
							|  |  |  |  |                            domain, port, | 
					
						
							|  |  |  |  |                            boxpath, httpPrefix, messageBodyJsonStr, | 
					
						
							|  |  |  |  |                            'rsa-sha256') | 
					
						
							| 
									
										
										
										
											2021-04-04 08:19:35 +00:00
										 |  |  |  |     expectedIndexHeader = \ | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |         'keyId="https://example.com/users/foo#main-key"; ' + \ | 
					
						
							| 
									
										
										
										
											2021-02-22 18:27:04 +00:00
										 |  |  |  |         'alg=hs2019; created=' + str(secondsSinceEpoch) + '; ' + \ | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |         'sig1=(*request-target, *created, host, date, ' + \ | 
					
						
							|  |  |  |  |         'digest, content-type, content-length)' | 
					
						
							| 
									
										
										
										
											2021-04-04 08:19:35 +00:00
										 |  |  |  |     if signatureIndexHeader != expectedIndexHeader: | 
					
						
							| 
									
										
										
										
											2021-04-04 08:27:46 +00:00
										 |  |  |  |         print('Unexpected new http header: ' + signatureIndexHeader) | 
					
						
							| 
									
										
										
										
											2021-04-04 20:34:42 +00:00
										 |  |  |  |         print('Should be:                  ' + expectedIndexHeader) | 
					
						
							| 
									
										
										
										
											2021-04-04 08:19:35 +00:00
										 |  |  |  |     assert signatureIndexHeader == expectedIndexHeader | 
					
						
							| 
									
										
										
										
											2021-02-22 18:20:33 +00:00
										 |  |  |  |     assert signatureHeader == \ | 
					
						
							| 
									
										
										
										
											2021-04-04 21:30:26 +00:00
										 |  |  |  |         'sig1=:euX3O1KSTYXN9/oR2qFezswWm9FbrjtRymK7xBpXNQvTs' + \ | 
					
						
							|  |  |  |  |         'XehtrNdD8nELZKzPXMvMz7PaJd6V+fjzpHoZ9upTdqqQLK2Iwml' + \ | 
					
						
							|  |  |  |  |         'p4BlHqW6Aopd7sZFCWFq7/Amm5oaizpp3e0jb5XISS5m3cRKuoi' + \ | 
					
						
							|  |  |  |  |         'LM0x+OudmAoYGi0TEEJk8bpnJAXfVCDfmOyL3XNqQeShQHeOANG' + \ | 
					
						
							|  |  |  |  |         'okiKktj8ff+KLYLaPTAJkob1k/EhoPIkbw/YzAY8IZjWQNMkf+F' + \ | 
					
						
							|  |  |  |  |         'JChApQ5HnDCQPwD5xV9eGzBpAf6D0G19xiTmQye4Hn6tAs3fy3V' + \ | 
					
						
							|  |  |  |  |         '/aYa/GhW2pSrctDnAKIi4imj9joppr3CB8gqgXZOPQ==:' | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |  | def _testHttpsigBase(withDigest): | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  |     print('testHttpsig(' + str(withDigest) + ')') | 
					
						
							| 
									
										
										
										
											2019-08-09 09:46:33 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     path = baseDir + '/.testHttpsigBase' | 
					
						
							| 
									
										
										
										
											2019-08-09 09:46:33 +00:00
										 |  |  |  |     if os.path.isdir(path): | 
					
						
							|  |  |  |  |         shutil.rmtree(path) | 
					
						
							|  |  |  |  |     os.mkdir(path) | 
					
						
							|  |  |  |  |     os.chdir(path) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     contentType = 'application/activity+json' | 
					
						
							|  |  |  |  |     nickname = 'socrates' | 
					
						
							|  |  |  |  |     domain = 'argumentative.social' | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     port = 5576 | 
					
						
							|  |  |  |  |     password = 'SuperSecretPassword' | 
					
						
							|  |  |  |  |     privateKeyPem, publicKeyPem, person, wfEndpoint = \ | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |         createPerson(path, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                      False, False, password) | 
					
						
							| 
									
										
										
										
											2019-08-09 09:46:33 +00:00
										 |  |  |  |     assert privateKeyPem | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     messageBodyJson = { | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |  |         "a key": "a value", | 
					
						
							|  |  |  |  |         "another key": "A string", | 
					
						
							|  |  |  |  |         "yet another key": "Another string" | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     messageBodyJsonStr = json.dumps(messageBodyJson) | 
					
						
							| 
									
										
										
										
											2019-07-01 09:31:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:19:16 +00:00
										 |  |  |  |     headersDomain = getFullDomain(domain, port) | 
					
						
							| 
									
										
										
										
											2019-07-01 09:31:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     dateStr = strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime()) | 
					
						
							|  |  |  |  |     boxpath = '/inbox' | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  |     if not withDigest: | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         headers = { | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |  |             'host': headersDomain, | 
					
						
							|  |  |  |  |             'date': dateStr, | 
					
						
							|  |  |  |  |             'content-type': 'application/json' | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         signatureHeader = \ | 
					
						
							|  |  |  |  |             signPostHeaders(dateStr, privateKeyPem, nickname, | 
					
						
							|  |  |  |  |                             domain, port, | 
					
						
							|  |  |  |  |                             domain, port, | 
					
						
							| 
									
										
										
										
											2019-08-16 13:47:01 +00:00
										 |  |  |  |                             boxpath, httpPrefix, None) | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         bodyDigest = messageContentDigest(messageBodyJsonStr) | 
					
						
							|  |  |  |  |         contentLength = len(messageBodyJsonStr) | 
					
						
							|  |  |  |  |         headers = { | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |  |             'host': headersDomain, | 
					
						
							|  |  |  |  |             'date': dateStr, | 
					
						
							|  |  |  |  |             'digest': f'SHA-256={bodyDigest}', | 
					
						
							|  |  |  |  |             'content-type': contentType, | 
					
						
							|  |  |  |  |             'content-length': str(contentLength) | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         signatureHeader = \ | 
					
						
							|  |  |  |  |             signPostHeaders(dateStr, privateKeyPem, nickname, | 
					
						
							|  |  |  |  |                             domain, port, | 
					
						
							|  |  |  |  |                             domain, port, | 
					
						
							| 
									
										
										
										
											2019-08-17 10:15:01 +00:00
										 |  |  |  |                             boxpath, httpPrefix, messageBodyJsonStr) | 
					
						
							| 
									
										
										
										
											2019-07-01 09:31:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     headers['signature'] = signatureHeader | 
					
						
							|  |  |  |  |     assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, | 
					
						
							|  |  |  |  |                              boxpath, False, None, | 
					
						
							|  |  |  |  |                              messageBodyJsonStr, False) | 
					
						
							| 
									
										
										
										
											2019-11-12 18:21:52 +00:00
										 |  |  |  |     if withDigest: | 
					
						
							|  |  |  |  |         # everything correct except for content-length | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         headers['content-length'] = str(contentLength + 2) | 
					
						
							|  |  |  |  |         assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, | 
					
						
							|  |  |  |  |                                  boxpath, False, None, | 
					
						
							|  |  |  |  |                                  messageBodyJsonStr, False) is False | 
					
						
							|  |  |  |  |     assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, | 
					
						
							|  |  |  |  |                              '/parambulator' + boxpath, False, None, | 
					
						
							|  |  |  |  |                              messageBodyJsonStr, False) is False | 
					
						
							|  |  |  |  |     assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, | 
					
						
							|  |  |  |  |                              boxpath, True, None, | 
					
						
							|  |  |  |  |                              messageBodyJsonStr, False) is False | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  |     if not withDigest: | 
					
						
							|  |  |  |  |         # fake domain | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         headers = { | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |  |             'host': 'bogon.domain', | 
					
						
							|  |  |  |  |             'date': dateStr, | 
					
						
							|  |  |  |  |             'content-type': 'application/json' | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  |     else: | 
					
						
							|  |  |  |  |         # correct domain but fake message | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         messageBodyJsonStr = \ | 
					
						
							|  |  |  |  |             '{"a key": "a value", "another key": "Fake GNUs", ' + \ | 
					
						
							|  |  |  |  |             '"yet another key": "More Fake GNUs"}' | 
					
						
							|  |  |  |  |         contentLength = len(messageBodyJsonStr) | 
					
						
							|  |  |  |  |         bodyDigest = messageContentDigest(messageBodyJsonStr) | 
					
						
							|  |  |  |  |         headers = { | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |  |             'host': domain, | 
					
						
							|  |  |  |  |             'date': dateStr, | 
					
						
							|  |  |  |  |             'digest': f'SHA-256={bodyDigest}', | 
					
						
							|  |  |  |  |             'content-type': contentType, | 
					
						
							|  |  |  |  |             'content-length': str(contentLength) | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     headers['signature'] = signatureHeader | 
					
						
							|  |  |  |  |     assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, | 
					
						
							|  |  |  |  |                              boxpath, True, None, | 
					
						
							|  |  |  |  |                              messageBodyJsonStr, False) is False | 
					
						
							| 
									
										
										
										
											2019-11-12 18:21:52 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 09:46:33 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(path) | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | def testHttpsig(): | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |  |     _testHttpsigBase(True) | 
					
						
							|  |  |  |  |     _testHttpsigBase(False) | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | def testCache(): | 
					
						
							|  |  |  |  |     print('testCache') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     personUrl = "cat@cardboard.box" | 
					
						
							|  |  |  |  |     personJson = { | 
					
						
							|  |  |  |  |         "id": 123456, | 
					
						
							|  |  |  |  |         "test": "This is a test" | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     personCache = {} | 
					
						
							| 
									
										
										
										
											2020-08-29 10:21:29 +00:00
										 |  |  |  |     storePersonInCache(None, personUrl, personJson, personCache, True) | 
					
						
							|  |  |  |  |     result = getPersonFromCache(None, personUrl, personCache, True) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert result['id'] == 123456 | 
					
						
							|  |  |  |  |     assert result['test'] == 'This is a test' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | def testThreadsFunction(param: str): | 
					
						
							|  |  |  |  |     for i in range(10000): | 
					
						
							|  |  |  |  |         time.sleep(2) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  | def testThreads(): | 
					
						
							|  |  |  |  |     print('testThreads') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     thr = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=testThreadsFunction, | 
					
						
							|  |  |  |  |                         args=('test',), | 
					
						
							|  |  |  |  |                         daemon=True) | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  |     thr.start() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thr.is_alive() is True | 
					
						
							| 
									
										
										
										
											2019-06-30 20:14:03 +00:00
										 |  |  |  |     time.sleep(1) | 
					
						
							|  |  |  |  |     thr.kill() | 
					
						
							|  |  |  |  |     thr.join() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thr.is_alive() is False | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | def createServerAlice(path: str, domain: str, port: int, | 
					
						
							|  |  |  |  |                       bobAddress: str, federationList: [], | 
					
						
							|  |  |  |  |                       hasFollows: bool, hasPosts: bool, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                       sendThreads: []): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('Creating test server: Alice on port ' + str(port)) | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     if os.path.isdir(path): | 
					
						
							|  |  |  |  |         shutil.rmtree(path) | 
					
						
							|  |  |  |  |     os.mkdir(path) | 
					
						
							|  |  |  |  |     os.chdir(path) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     nickname = 'alice' | 
					
						
							|  |  |  |  |     httpPrefix = 'http' | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     proxyType = None | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     password = 'alicepass' | 
					
						
							|  |  |  |  |     maxReplies = 64 | 
					
						
							|  |  |  |  |     domainMaxPostsPerDay = 1000 | 
					
						
							|  |  |  |  |     accountMaxPostsPerDay = 1000 | 
					
						
							|  |  |  |  |     allowDeletion = True | 
					
						
							|  |  |  |  |     privateKeyPem, publicKeyPem, person, wfEndpoint = \ | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |         createPerson(path, nickname, domain, port, httpPrefix, True, | 
					
						
							|  |  |  |  |                      False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     deleteAllPosts(path, nickname, domain, 'inbox') | 
					
						
							|  |  |  |  |     deleteAllPosts(path, nickname, domain, 'outbox') | 
					
						
							|  |  |  |  |     assert setSkillLevel(path, nickname, domain, 'hacking', 90) | 
					
						
							| 
									
										
										
										
											2021-05-13 19:58:16 +00:00
										 |  |  |  |     assert setRole(path, nickname, domain, 'guru') | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |  |     if hasFollows: | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         followPerson(path, nickname, domain, 'bob', bobAddress, | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |         followerOfPerson(path, nickname, domain, 'bob', bobAddress, | 
					
						
							|  |  |  |  |                          federationList, False) | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |  |     if hasPosts: | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |         testFollowersOnly = False | 
					
						
							|  |  |  |  |         testSaveToFile = True | 
					
						
							| 
									
										
										
										
											2020-12-22 21:27:46 +00:00
										 |  |  |  |         clientToServer = False | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |         testCommentsEnabled = True | 
					
						
							|  |  |  |  |         testAttachImageFilename = None | 
					
						
							|  |  |  |  |         testMediaType = None | 
					
						
							|  |  |  |  |         testImageDescription = None | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |         testCity = 'London, England' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         createPublicPost(path, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                          "No wise fish would go anywhere without a porpoise", | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                          testFollowersOnly, | 
					
						
							|  |  |  |  |                          testSaveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, | 
					
						
							|  |  |  |  |                          testCommentsEnabled, | 
					
						
							|  |  |  |  |                          testAttachImageFilename, | 
					
						
							|  |  |  |  |                          testMediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          testImageDescription, testCity) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         createPublicPost(path, nickname, domain, port, httpPrefix, | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                          "Curiouser and curiouser!", | 
					
						
							|  |  |  |  |                          testFollowersOnly, | 
					
						
							|  |  |  |  |                          testSaveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, | 
					
						
							|  |  |  |  |                          testCommentsEnabled, | 
					
						
							|  |  |  |  |                          testAttachImageFilename, | 
					
						
							|  |  |  |  |                          testMediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          testImageDescription, testCity) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         createPublicPost(path, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                          "In the gardens of memory, in the palace " + | 
					
						
							|  |  |  |  |                          "of dreams, that is where you and I shall meet", | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                          testFollowersOnly, | 
					
						
							|  |  |  |  |                          testSaveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, | 
					
						
							|  |  |  |  |                          testCommentsEnabled, | 
					
						
							|  |  |  |  |                          testAttachImageFilename, | 
					
						
							|  |  |  |  |                          testMediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          testImageDescription, testCity) | 
					
						
							| 
									
										
										
										
											2019-06-30 21:27:25 +00:00
										 |  |  |  |     global testServerAliceRunning | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testServerAliceRunning = True | 
					
						
							|  |  |  |  |     maxMentions = 10 | 
					
						
							|  |  |  |  |     maxEmoji = 10 | 
					
						
							|  |  |  |  |     onionDomain = None | 
					
						
							| 
									
										
										
										
											2020-06-03 17:38:34 +00:00
										 |  |  |  |     i2pDomain = None | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     allowLocalNetworkAccess = True | 
					
						
							| 
									
										
										
										
											2020-11-22 11:48:53 +00:00
										 |  |  |  |     maxNewswirePosts = 20 | 
					
						
							| 
									
										
										
										
											2020-12-13 12:44:17 +00:00
										 |  |  |  |     dormantMonths = 3 | 
					
						
							| 
									
										
										
										
											2020-12-18 11:48:00 +00:00
										 |  |  |  |     sendThreadsTimeoutMins = 30 | 
					
						
							| 
									
										
										
										
											2020-12-26 10:22:56 +00:00
										 |  |  |  |     maxFollowers = 10 | 
					
						
							| 
									
										
										
										
											2021-01-05 10:29:37 +00:00
										 |  |  |  |     verifyAllSignatures = True | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |  |     brochMode = False | 
					
						
							| 
									
										
										
										
											2021-05-03 10:05:05 +00:00
										 |  |  |  |     showNodeInfoAccounts = True | 
					
						
							|  |  |  |  |     showNodeInfoVersion = True | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     print('Server running: Alice') | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     runDaemon(city, | 
					
						
							|  |  |  |  |               showNodeInfoAccounts, | 
					
						
							| 
									
										
										
										
											2021-05-03 10:05:05 +00:00
										 |  |  |  |               showNodeInfoVersion, | 
					
						
							|  |  |  |  |               brochMode, | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |  |               verifyAllSignatures, | 
					
						
							| 
									
										
										
										
											2021-01-05 10:29:37 +00:00
										 |  |  |  |               sendThreadsTimeoutMins, | 
					
						
							| 
									
										
										
										
											2020-12-18 11:48:00 +00:00
										 |  |  |  |               dormantMonths, maxNewswirePosts, | 
					
						
							| 
									
										
										
										
											2020-12-13 12:44:17 +00:00
										 |  |  |  |               allowLocalNetworkAccess, | 
					
						
							| 
									
										
										
										
											2020-12-26 10:22:56 +00:00
										 |  |  |  |               2048, False, True, False, False, True, maxFollowers, | 
					
						
							| 
									
										
										
										
											2020-10-26 20:32:01 +00:00
										 |  |  |  |               0, 100, 1024, 5, False, | 
					
						
							| 
									
										
										
										
											2020-10-23 19:18:13 +00:00
										 |  |  |  |               0, False, 1, False, False, False, | 
					
						
							| 
									
										
										
										
											2020-10-07 09:10:42 +00:00
										 |  |  |  |               5, True, True, 'en', __version__, | 
					
						
							| 
									
										
										
										
											2020-06-03 17:38:34 +00:00
										 |  |  |  |               "instanceId", False, path, domain, | 
					
						
							| 
									
										
										
										
											2020-08-02 09:51:20 +00:00
										 |  |  |  |               onionDomain, i2pDomain, None, port, port, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |               httpPrefix, federationList, maxMentions, maxEmoji, False, | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |               proxyType, maxReplies, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |               domainMaxPostsPerDay, accountMaxPostsPerDay, | 
					
						
							| 
									
										
										
										
											2021-01-07 15:38:55 +00:00
										 |  |  |  |               allowDeletion, True, True, False, sendThreads, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |               False) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | def createServerBob(path: str, domain: str, port: int, | 
					
						
							|  |  |  |  |                     aliceAddress: str, federationList: [], | 
					
						
							|  |  |  |  |                     hasFollows: bool, hasPosts: bool, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                     sendThreads: []): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('Creating test server: Bob on port ' + str(port)) | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     if os.path.isdir(path): | 
					
						
							|  |  |  |  |         shutil.rmtree(path) | 
					
						
							|  |  |  |  |     os.mkdir(path) | 
					
						
							|  |  |  |  |     os.chdir(path) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     nickname = 'bob' | 
					
						
							|  |  |  |  |     httpPrefix = 'http' | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     proxyType = None | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     clientToServer = False | 
					
						
							|  |  |  |  |     password = 'bobpass' | 
					
						
							|  |  |  |  |     maxReplies = 64 | 
					
						
							|  |  |  |  |     domainMaxPostsPerDay = 1000 | 
					
						
							|  |  |  |  |     accountMaxPostsPerDay = 1000 | 
					
						
							|  |  |  |  |     allowDeletion = True | 
					
						
							|  |  |  |  |     privateKeyPem, publicKeyPem, person, wfEndpoint = \ | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |         createPerson(path, nickname, domain, port, httpPrefix, True, | 
					
						
							|  |  |  |  |                      False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     deleteAllPosts(path, nickname, domain, 'inbox') | 
					
						
							|  |  |  |  |     deleteAllPosts(path, nickname, domain, 'outbox') | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |  |     if hasFollows: | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         followPerson(path, nickname, domain, | 
					
						
							|  |  |  |  |                      'alice', aliceAddress, federationList, False) | 
					
						
							|  |  |  |  |         followerOfPerson(path, nickname, domain, | 
					
						
							|  |  |  |  |                          'alice', aliceAddress, federationList, False) | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |  |     if hasPosts: | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |         testFollowersOnly = False | 
					
						
							|  |  |  |  |         testSaveToFile = True | 
					
						
							|  |  |  |  |         testCommentsEnabled = True | 
					
						
							|  |  |  |  |         testAttachImageFilename = None | 
					
						
							| 
									
										
										
										
											2020-12-22 21:27:46 +00:00
										 |  |  |  |         testImageDescription = None | 
					
						
							|  |  |  |  |         testMediaType = None | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |         testCity = 'London, England' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         createPublicPost(path, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                          "It's your life, live it your way.", | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                          testFollowersOnly, | 
					
						
							|  |  |  |  |                          testSaveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, | 
					
						
							|  |  |  |  |                          testCommentsEnabled, | 
					
						
							|  |  |  |  |                          testAttachImageFilename, | 
					
						
							|  |  |  |  |                          testMediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          testImageDescription, testCity) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         createPublicPost(path, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                          "One of the things I've realised is that " + | 
					
						
							|  |  |  |  |                          "I am very simple", | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                          testFollowersOnly, | 
					
						
							|  |  |  |  |                          testSaveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, | 
					
						
							|  |  |  |  |                          testCommentsEnabled, | 
					
						
							|  |  |  |  |                          testAttachImageFilename, | 
					
						
							|  |  |  |  |                          testMediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          testImageDescription, testCity) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         createPublicPost(path, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                          "Quantum physics is a bit of a passion of mine", | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                          testFollowersOnly, | 
					
						
							|  |  |  |  |                          testSaveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, | 
					
						
							|  |  |  |  |                          testCommentsEnabled, | 
					
						
							|  |  |  |  |                          testAttachImageFilename, | 
					
						
							|  |  |  |  |                          testMediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          testImageDescription, testCity) | 
					
						
							| 
									
										
										
										
											2019-06-30 21:27:25 +00:00
										 |  |  |  |     global testServerBobRunning | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testServerBobRunning = True | 
					
						
							|  |  |  |  |     maxMentions = 10 | 
					
						
							|  |  |  |  |     maxEmoji = 10 | 
					
						
							|  |  |  |  |     onionDomain = None | 
					
						
							| 
									
										
										
										
											2020-06-03 17:38:34 +00:00
										 |  |  |  |     i2pDomain = None | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     allowLocalNetworkAccess = True | 
					
						
							| 
									
										
										
										
											2020-11-22 11:48:53 +00:00
										 |  |  |  |     maxNewswirePosts = 20 | 
					
						
							| 
									
										
										
										
											2020-12-13 12:44:17 +00:00
										 |  |  |  |     dormantMonths = 3 | 
					
						
							| 
									
										
										
										
											2020-12-18 11:48:00 +00:00
										 |  |  |  |     sendThreadsTimeoutMins = 30 | 
					
						
							| 
									
										
										
										
											2020-12-26 10:22:56 +00:00
										 |  |  |  |     maxFollowers = 10 | 
					
						
							| 
									
										
										
										
											2021-01-05 10:29:37 +00:00
										 |  |  |  |     verifyAllSignatures = True | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |  |     brochMode = False | 
					
						
							| 
									
										
										
										
											2021-05-03 10:05:05 +00:00
										 |  |  |  |     showNodeInfoAccounts = True | 
					
						
							|  |  |  |  |     showNodeInfoVersion = True | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     print('Server running: Bob') | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     runDaemon(city, | 
					
						
							|  |  |  |  |               showNodeInfoAccounts, | 
					
						
							| 
									
										
										
										
											2021-05-03 10:05:05 +00:00
										 |  |  |  |               showNodeInfoVersion, | 
					
						
							|  |  |  |  |               brochMode, | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |  |               verifyAllSignatures, | 
					
						
							| 
									
										
										
										
											2021-01-05 10:29:37 +00:00
										 |  |  |  |               sendThreadsTimeoutMins, | 
					
						
							| 
									
										
										
										
											2020-12-18 11:48:00 +00:00
										 |  |  |  |               dormantMonths, maxNewswirePosts, | 
					
						
							| 
									
										
										
										
											2020-12-13 12:44:17 +00:00
										 |  |  |  |               allowLocalNetworkAccess, | 
					
						
							| 
									
										
										
										
											2020-12-26 10:22:56 +00:00
										 |  |  |  |               2048, False, True, False, False, True, maxFollowers, | 
					
						
							| 
									
										
										
										
											2020-10-26 20:32:01 +00:00
										 |  |  |  |               0, 100, 1024, 5, False, 0, | 
					
						
							| 
									
										
										
										
											2020-10-23 19:18:13 +00:00
										 |  |  |  |               False, 1, False, False, False, | 
					
						
							| 
									
										
										
										
											2020-10-07 09:10:42 +00:00
										 |  |  |  |               5, True, True, 'en', __version__, | 
					
						
							| 
									
										
										
										
											2020-06-03 17:38:34 +00:00
										 |  |  |  |               "instanceId", False, path, domain, | 
					
						
							| 
									
										
										
										
											2020-08-02 09:51:20 +00:00
										 |  |  |  |               onionDomain, i2pDomain, None, port, port, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |               httpPrefix, federationList, maxMentions, maxEmoji, False, | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |               proxyType, maxReplies, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |               domainMaxPostsPerDay, accountMaxPostsPerDay, | 
					
						
							| 
									
										
										
										
											2021-01-07 15:38:55 +00:00
										 |  |  |  |               allowDeletion, True, True, False, sendThreads, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |               False) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | def createServerEve(path: str, domain: str, port: int, federationList: [], | 
					
						
							|  |  |  |  |                     hasFollows: bool, hasPosts: bool, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                     sendThreads: []): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('Creating test server: Eve on port ' + str(port)) | 
					
						
							| 
									
										
										
										
											2019-07-07 19:25:38 +00:00
										 |  |  |  |     if os.path.isdir(path): | 
					
						
							|  |  |  |  |         shutil.rmtree(path) | 
					
						
							|  |  |  |  |     os.mkdir(path) | 
					
						
							|  |  |  |  |     os.chdir(path) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     nickname = 'eve' | 
					
						
							|  |  |  |  |     httpPrefix = 'http' | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     proxyType = None | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     password = 'evepass' | 
					
						
							|  |  |  |  |     maxReplies = 64 | 
					
						
							|  |  |  |  |     allowDeletion = True | 
					
						
							|  |  |  |  |     privateKeyPem, publicKeyPem, person, wfEndpoint = \ | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |         createPerson(path, nickname, domain, port, httpPrefix, True, | 
					
						
							|  |  |  |  |                      False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     deleteAllPosts(path, nickname, domain, 'inbox') | 
					
						
							|  |  |  |  |     deleteAllPosts(path, nickname, domain, 'outbox') | 
					
						
							| 
									
										
										
										
											2019-07-07 19:25:38 +00:00
										 |  |  |  |     global testServerEveRunning | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testServerEveRunning = True | 
					
						
							|  |  |  |  |     maxMentions = 10 | 
					
						
							|  |  |  |  |     maxEmoji = 10 | 
					
						
							|  |  |  |  |     onionDomain = None | 
					
						
							| 
									
										
										
										
											2020-06-03 17:38:34 +00:00
										 |  |  |  |     i2pDomain = None | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     allowLocalNetworkAccess = True | 
					
						
							| 
									
										
										
										
											2020-11-22 11:48:53 +00:00
										 |  |  |  |     maxNewswirePosts = 20 | 
					
						
							| 
									
										
										
										
											2020-12-13 12:44:17 +00:00
										 |  |  |  |     dormantMonths = 3 | 
					
						
							| 
									
										
										
										
											2020-12-18 11:48:00 +00:00
										 |  |  |  |     sendThreadsTimeoutMins = 30 | 
					
						
							| 
									
										
										
										
											2020-12-26 10:22:56 +00:00
										 |  |  |  |     maxFollowers = 10 | 
					
						
							| 
									
										
										
										
											2021-01-05 10:29:37 +00:00
										 |  |  |  |     verifyAllSignatures = True | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |  |     brochMode = False | 
					
						
							| 
									
										
										
										
											2021-05-03 10:05:05 +00:00
										 |  |  |  |     showNodeInfoAccounts = True | 
					
						
							|  |  |  |  |     showNodeInfoVersion = True | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2019-07-07 19:25:38 +00:00
										 |  |  |  |     print('Server running: Eve') | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     runDaemon(city, | 
					
						
							|  |  |  |  |               showNodeInfoAccounts, | 
					
						
							| 
									
										
										
										
											2021-05-03 10:05:05 +00:00
										 |  |  |  |               showNodeInfoVersion, | 
					
						
							|  |  |  |  |               brochMode, | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |  |               verifyAllSignatures, | 
					
						
							| 
									
										
										
										
											2021-01-05 10:29:37 +00:00
										 |  |  |  |               sendThreadsTimeoutMins, | 
					
						
							| 
									
										
										
										
											2020-12-18 11:48:00 +00:00
										 |  |  |  |               dormantMonths, maxNewswirePosts, | 
					
						
							| 
									
										
										
										
											2020-12-13 12:44:17 +00:00
										 |  |  |  |               allowLocalNetworkAccess, | 
					
						
							| 
									
										
										
										
											2020-12-26 10:22:56 +00:00
										 |  |  |  |               2048, False, True, False, False, True, maxFollowers, | 
					
						
							| 
									
										
										
										
											2020-10-26 20:32:01 +00:00
										 |  |  |  |               0, 100, 1024, 5, False, 0, | 
					
						
							| 
									
										
										
										
											2020-10-23 19:18:13 +00:00
										 |  |  |  |               False, 1, False, False, False, | 
					
						
							| 
									
										
										
										
											2020-10-07 09:10:42 +00:00
										 |  |  |  |               5, True, True, 'en', __version__, | 
					
						
							| 
									
										
										
										
											2020-06-03 17:38:34 +00:00
										 |  |  |  |               "instanceId", False, path, domain, | 
					
						
							| 
									
										
										
										
											2020-08-02 09:51:20 +00:00
										 |  |  |  |               onionDomain, i2pDomain, None, port, port, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |               httpPrefix, federationList, maxMentions, maxEmoji, False, | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |               proxyType, maxReplies, allowDeletion, True, True, False, | 
					
						
							| 
									
										
										
										
											2021-01-07 15:38:55 +00:00
										 |  |  |  |               sendThreads, False) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-07 19:25:38 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | def testPostMessageBetweenServers(): | 
					
						
							|  |  |  |  |     print('Testing sending message from one server to the inbox of another') | 
					
						
							| 
									
										
										
										
											2019-06-30 21:27:25 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     global testServerAliceRunning | 
					
						
							|  |  |  |  |     global testServerBobRunning | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testServerAliceRunning = False | 
					
						
							|  |  |  |  |     testServerBobRunning = False | 
					
						
							| 
									
										
										
										
											2019-06-30 21:27:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     httpPrefix = 'http' | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     proxyType = None | 
					
						
							| 
									
										
										
										
											2019-06-30 22:56:37 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     if os.path.isdir(baseDir + '/.tests'): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir + '/.tests') | 
					
						
							|  |  |  |  |     os.mkdir(baseDir + '/.tests') | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # create the servers | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     aliceDir = baseDir + '/.tests/alice' | 
					
						
							|  |  |  |  |     aliceDomain = '127.0.0.50' | 
					
						
							|  |  |  |  |     alicePort = 61935 | 
					
						
							|  |  |  |  |     aliceAddress = aliceDomain + ':' + str(alicePort) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     bobDir = baseDir + '/.tests/bob' | 
					
						
							|  |  |  |  |     bobDomain = '127.0.0.100' | 
					
						
							|  |  |  |  |     bobPort = 61936 | 
					
						
							|  |  |  |  |     federationList = [bobDomain, aliceDomain] | 
					
						
							|  |  |  |  |     aliceSendThreads = [] | 
					
						
							|  |  |  |  |     bobSendThreads = [] | 
					
						
							|  |  |  |  |     bobAddress = bobDomain + ':' + str(bobPort) | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |     global thrAlice | 
					
						
							|  |  |  |  |     if thrAlice: | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |         while thrAlice.is_alive(): | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |             thrAlice.stop() | 
					
						
							|  |  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |  |         thrAlice.kill() | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     thrAlice = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=createServerAlice, | 
					
						
							|  |  |  |  |                         args=(aliceDir, aliceDomain, alicePort, bobAddress, | 
					
						
							|  |  |  |  |                               federationList, False, False, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                               aliceSendThreads), | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                         daemon=True) | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     global thrBob | 
					
						
							|  |  |  |  |     if thrBob: | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |         while thrBob.is_alive(): | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |             thrBob.stop() | 
					
						
							|  |  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |  |         thrBob.kill() | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     thrBob = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=createServerBob, | 
					
						
							|  |  |  |  |                         args=(bobDir, bobDomain, bobPort, aliceAddress, | 
					
						
							|  |  |  |  |                               federationList, False, False, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                               bobSendThreads), | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                         daemon=True) | 
					
						
							| 
									
										
										
										
											2019-07-01 21:01:43 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrAlice.start() | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     thrBob.start() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrAlice.is_alive() is True | 
					
						
							|  |  |  |  |     assert thrBob.is_alive() is True | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 21:27:25 +00:00
										 |  |  |  |     # wait for both servers to be running | 
					
						
							|  |  |  |  |     while not (testServerAliceRunning and testServerBobRunning): | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 20:25:19 +00:00
										 |  |  |  |     time.sleep(1) | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |  |     print('\n\n*******************************************************') | 
					
						
							| 
									
										
										
										
											2019-06-30 22:56:37 +00:00
										 |  |  |  |     print('Alice sends to Bob') | 
					
						
							|  |  |  |  |     os.chdir(aliceDir) | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     sessionAlice = createSession(proxyType) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     inReplyTo = None | 
					
						
							|  |  |  |  |     inReplyToAtomUri = None | 
					
						
							|  |  |  |  |     subject = None | 
					
						
							|  |  |  |  |     alicePostLog = [] | 
					
						
							|  |  |  |  |     followersOnly = False | 
					
						
							|  |  |  |  |     saveToFile = True | 
					
						
							|  |  |  |  |     clientToServer = False | 
					
						
							|  |  |  |  |     ccUrl = None | 
					
						
							|  |  |  |  |     alicePersonCache = {} | 
					
						
							|  |  |  |  |     aliceCachedWebfingers = {} | 
					
						
							|  |  |  |  |     attachedImageFilename = baseDir + '/img/logo.png' | 
					
						
							|  |  |  |  |     mediaType = getAttachmentMediaType(attachedImageFilename) | 
					
						
							|  |  |  |  |     attachedImageDescription = 'Logo' | 
					
						
							|  |  |  |  |     isArticle = False | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |  |     # nothing in Alice's outbox | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     outboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/outbox' | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 0 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     sendResult = \ | 
					
						
							|  |  |  |  |         sendPost(__version__, | 
					
						
							|  |  |  |  |                  sessionAlice, aliceDir, 'alice', aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                  'bob', bobDomain, bobPort, ccUrl, httpPrefix, | 
					
						
							|  |  |  |  |                  'Why is a mouse when it spins? ' + | 
					
						
							|  |  |  |  |                  'यह एक परीक्षण है #sillyquestion', | 
					
						
							|  |  |  |  |                  followersOnly, | 
					
						
							| 
									
										
										
										
											2020-08-21 17:40:50 +00:00
										 |  |  |  |                  saveToFile, clientToServer, True, | 
					
						
							|  |  |  |  |                  attachedImageFilename, mediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                  attachedImageDescription, city, federationList, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                  aliceSendThreads, alicePostLog, aliceCachedWebfingers, | 
					
						
							|  |  |  |  |                  alicePersonCache, isArticle, inReplyTo, | 
					
						
							|  |  |  |  |                  inReplyToAtomUri, subject) | 
					
						
							|  |  |  |  |     print('sendResult: ' + str(sendResult)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue' | 
					
						
							|  |  |  |  |     inboxPath = bobDir + '/accounts/bob@' + bobDomain + '/inbox' | 
					
						
							|  |  |  |  |     mPath = getMediaPath() | 
					
						
							|  |  |  |  |     mediaPath = aliceDir + '/' + mPath | 
					
						
							| 
									
										
										
										
											2019-07-07 22:25:22 +00:00
										 |  |  |  |     for i in range(30): | 
					
						
							| 
									
										
										
										
											2019-07-04 20:36:12 +00:00
										 |  |  |  |         if os.path.isdir(inboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             if len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                     if os.path.isfile(os.path.join(inboxPath, name))]) > 0: | 
					
						
							|  |  |  |  |                 if len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                         if os.path.isfile(os.path.join(outboxPath, | 
					
						
							|  |  |  |  |                                                        name))]) == 1: | 
					
						
							|  |  |  |  |                     if len([name for name in os.listdir(mediaPath) | 
					
						
							|  |  |  |  |                             if os.path.isfile(os.path.join(mediaPath, | 
					
						
							|  |  |  |  |                                                            name))]) > 0: | 
					
						
							|  |  |  |  |                         if len([name for name in os.listdir(queuePath) | 
					
						
							|  |  |  |  |                                 if os.path.isfile(os.path.join(queuePath, | 
					
						
							|  |  |  |  |                                                                name))]) == 0: | 
					
						
							| 
									
										
										
										
											2019-10-19 17:50:05 +00:00
										 |  |  |  |                             break | 
					
						
							| 
									
										
										
										
											2019-07-01 21:01:43 +00:00
										 |  |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											2019-07-09 08:52:53 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-06 15:05:22 +00:00
										 |  |  |  |     # check that a news account exists | 
					
						
							|  |  |  |  |     newsActorDir = aliceDir + '/accounts/news@' + aliceDomain | 
					
						
							|  |  |  |  |     print("newsActorDir: " + newsActorDir) | 
					
						
							|  |  |  |  |     assert os.path.isdir(newsActorDir) | 
					
						
							|  |  |  |  |     newsActorFile = newsActorDir + '.json' | 
					
						
							|  |  |  |  |     assert os.path.isfile(newsActorFile) | 
					
						
							|  |  |  |  |     newsActorJson = loadJson(newsActorFile) | 
					
						
							|  |  |  |  |     assert newsActorJson | 
					
						
							|  |  |  |  |     assert newsActorJson.get("id") | 
					
						
							|  |  |  |  |     # check the id of the news actor | 
					
						
							|  |  |  |  |     print('News actor Id: ' + newsActorJson["id"]) | 
					
						
							|  |  |  |  |     assert (newsActorJson["id"] == | 
					
						
							|  |  |  |  |             httpPrefix + '://' + aliceAddress + '/users/news') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-12 19:26:54 +00:00
										 |  |  |  |     # Image attachment created | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len([name for name in os.listdir(mediaPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(mediaPath, name))]) > 0 | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |  |     # inbox item created | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) == 1 | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |  |     # queue item removed | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testval = len([name for name in os.listdir(queuePath) | 
					
						
							|  |  |  |  |                    if os.path.isfile(os.path.join(queuePath, name))]) | 
					
						
							|  |  |  |  |     print('queuePath: ' + queuePath + ' '+str(testval)) | 
					
						
							|  |  |  |  |     assert testval == 0 | 
					
						
							|  |  |  |  |     assert validInbox(bobDir, 'bob', bobDomain) | 
					
						
							|  |  |  |  |     assert validInboxFilenames(bobDir, 'bob', bobDomain, | 
					
						
							|  |  |  |  |                                aliceDomain, alicePort) | 
					
						
							| 
									
										
										
										
											2019-11-09 09:50:58 +00:00
										 |  |  |  |     print('Check that message received from Alice contains the expected text') | 
					
						
							|  |  |  |  |     for name in os.listdir(inboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         filename = os.path.join(inboxPath, name) | 
					
						
							| 
									
										
										
										
											2019-11-09 09:50:58 +00:00
										 |  |  |  |         assert os.path.isfile(filename) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         receivedJson = loadJson(filename, 0) | 
					
						
							| 
									
										
										
										
											2019-11-23 10:08:00 +00:00
										 |  |  |  |         if receivedJson: | 
					
						
							| 
									
										
										
										
											2019-11-09 09:50:58 +00:00
										 |  |  |  |             pprint(receivedJson['object']['content']) | 
					
						
							| 
									
										
										
										
											2019-11-09 09:52:09 +00:00
										 |  |  |  |         assert receivedJson | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         assert 'Why is a mouse when it spins?' in \ | 
					
						
							|  |  |  |  |             receivedJson['object']['content'] | 
					
						
							| 
									
										
										
										
											2019-11-09 09:52:09 +00:00
										 |  |  |  |         assert 'यह एक परीक्षण है' in receivedJson['object']['content'] | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-11 12:59:00 +00:00
										 |  |  |  |     print('\n\n*******************************************************') | 
					
						
							|  |  |  |  |     print("Bob likes Alice's post") | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |     aliceDomainStr = aliceDomain + ':' + str(alicePort) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     followerOfPerson(bobDir, 'bob', bobDomain, 'alice', | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                      aliceDomainStr, federationList, False) | 
					
						
							|  |  |  |  |     bobDomainStr = bobDomain + ':' + str(bobPort) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     followPerson(aliceDir, 'alice', aliceDomain, 'bob', | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                  bobDomainStr, federationList, False) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     sessionBob = createSession(proxyType) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     bobPostLog = [] | 
					
						
							|  |  |  |  |     bobPersonCache = {} | 
					
						
							|  |  |  |  |     bobCachedWebfingers = {} | 
					
						
							|  |  |  |  |     statusNumber = None | 
					
						
							|  |  |  |  |     outboxPostFilename = None | 
					
						
							|  |  |  |  |     outboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/outbox' | 
					
						
							| 
									
										
										
										
											2019-07-11 12:59:00 +00:00
										 |  |  |  |     for name in os.listdir(outboxPath): | 
					
						
							|  |  |  |  |         if '#statuses#' in name: | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             statusNumber = \ | 
					
						
							|  |  |  |  |                 int(name.split('#statuses#')[1].replace('.json', '')) | 
					
						
							|  |  |  |  |             outboxPostFilename = outboxPath + '/' + name | 
					
						
							|  |  |  |  |     assert statusNumber > 0 | 
					
						
							| 
									
										
										
										
											2019-07-11 12:59:00 +00:00
										 |  |  |  |     assert outboxPostFilename | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert likePost({}, sessionBob, bobDir, federationList, | 
					
						
							|  |  |  |  |                     'bob', bobDomain, bobPort, httpPrefix, | 
					
						
							|  |  |  |  |                     'alice', aliceDomain, alicePort, [], | 
					
						
							|  |  |  |  |                     statusNumber, False, bobSendThreads, bobPostLog, | 
					
						
							|  |  |  |  |                     bobPersonCache, bobCachedWebfingers, | 
					
						
							|  |  |  |  |                     True, __version__) | 
					
						
							| 
									
										
										
										
											2019-07-11 12:59:00 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     for i in range(20): | 
					
						
							|  |  |  |  |         if 'likes' in open(outboxPostFilename).read(): | 
					
						
							|  |  |  |  |             break | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     alicePostJson = loadJson(outboxPostFilename, 0) | 
					
						
							| 
									
										
										
										
											2019-11-23 10:08:00 +00:00
										 |  |  |  |     if alicePostJson: | 
					
						
							| 
									
										
										
										
											2019-07-11 12:59:00 +00:00
										 |  |  |  |         pprint(alicePostJson) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-11 12:59:00 +00:00
										 |  |  |  |     assert 'likes' in open(outboxPostFilename).read() | 
					
						
							| 
									
										
										
										
											2019-07-11 17:55:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     print('\n\n*******************************************************') | 
					
						
							|  |  |  |  |     print("Bob repeats Alice's post") | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     objectUrl = \ | 
					
						
							|  |  |  |  |         httpPrefix + '://' + aliceDomain + ':' + str(alicePort) + \ | 
					
						
							|  |  |  |  |         '/users/alice/statuses/' + str(statusNumber) | 
					
						
							|  |  |  |  |     inboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/inbox' | 
					
						
							|  |  |  |  |     outboxPath = bobDir + '/accounts/bob@' + bobDomain + '/outbox' | 
					
						
							|  |  |  |  |     outboxBeforeAnnounceCount = \ | 
					
						
							|  |  |  |  |         len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |              if os.path.isfile(os.path.join(outboxPath, name))]) | 
					
						
							|  |  |  |  |     beforeAnnounceCount = \ | 
					
						
							|  |  |  |  |         len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |              if os.path.isfile(os.path.join(inboxPath, name))]) | 
					
						
							|  |  |  |  |     print('inbox items before announce: ' + str(beforeAnnounceCount)) | 
					
						
							|  |  |  |  |     print('outbox items before announce: ' + str(outboxBeforeAnnounceCount)) | 
					
						
							|  |  |  |  |     assert outboxBeforeAnnounceCount == 0 | 
					
						
							|  |  |  |  |     assert beforeAnnounceCount == 0 | 
					
						
							|  |  |  |  |     announcePublic(sessionBob, bobDir, federationList, | 
					
						
							|  |  |  |  |                    'bob', bobDomain, bobPort, httpPrefix, | 
					
						
							|  |  |  |  |                    objectUrl, | 
					
						
							|  |  |  |  |                    False, bobSendThreads, bobPostLog, | 
					
						
							|  |  |  |  |                    bobPersonCache, bobCachedWebfingers, | 
					
						
							|  |  |  |  |                    True, __version__) | 
					
						
							|  |  |  |  |     announceMessageArrived = False | 
					
						
							|  |  |  |  |     outboxMessageArrived = False | 
					
						
							| 
									
										
										
										
											2019-07-11 19:31:02 +00:00
										 |  |  |  |     for i in range(10): | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											2020-03-27 19:54:41 +00:00
										 |  |  |  |         if not os.path.isdir(inboxPath): | 
					
						
							|  |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         if len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) > 0: | 
					
						
							|  |  |  |  |             outboxMessageArrived = True | 
					
						
							| 
									
										
										
										
											2020-03-27 19:54:41 +00:00
										 |  |  |  |             print('Announce created by Bob') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         if len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) > 0: | 
					
						
							|  |  |  |  |             announceMessageArrived = True | 
					
						
							| 
									
										
										
										
											2020-03-27 19:54:41 +00:00
										 |  |  |  |             print('Announce message sent to Alice!') | 
					
						
							|  |  |  |  |         if announceMessageArrived and outboxMessageArrived: | 
					
						
							|  |  |  |  |             break | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     afterAnnounceCount = \ | 
					
						
							|  |  |  |  |         len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |              if os.path.isfile(os.path.join(inboxPath, name))]) | 
					
						
							|  |  |  |  |     outboxAfterAnnounceCount = \ | 
					
						
							|  |  |  |  |         len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |              if os.path.isfile(os.path.join(outboxPath, name))]) | 
					
						
							|  |  |  |  |     print('inbox items after announce: ' + str(afterAnnounceCount)) | 
					
						
							|  |  |  |  |     print('outbox items after announce: ' + str(outboxAfterAnnounceCount)) | 
					
						
							|  |  |  |  |     assert afterAnnounceCount == beforeAnnounceCount+1 | 
					
						
							|  |  |  |  |     assert outboxAfterAnnounceCount == outboxBeforeAnnounceCount + 1 | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     # stop the servers | 
					
						
							|  |  |  |  |     thrAlice.kill() | 
					
						
							|  |  |  |  |     thrAlice.join() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrAlice.is_alive() is False | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrBob.kill() | 
					
						
							|  |  |  |  |     thrBob.join() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrBob.is_alive() is False | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 12:35:29 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(aliceDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(bobDir) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | def testFollowBetweenServers(): | 
					
						
							|  |  |  |  |     print('Testing sending a follow request from one server to another') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     global testServerAliceRunning | 
					
						
							|  |  |  |  |     global testServerBobRunning | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testServerAliceRunning = False | 
					
						
							|  |  |  |  |     testServerBobRunning = False | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     httpPrefix = 'http' | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     proxyType = None | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     federationList = [] | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     if os.path.isdir(baseDir + '/.tests'): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir + '/.tests') | 
					
						
							|  |  |  |  |     os.mkdir(baseDir + '/.tests') | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # create the servers | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     aliceDir = baseDir + '/.tests/alice' | 
					
						
							|  |  |  |  |     aliceDomain = '127.0.0.47' | 
					
						
							|  |  |  |  |     alicePort = 61935 | 
					
						
							|  |  |  |  |     aliceSendThreads = [] | 
					
						
							|  |  |  |  |     aliceAddress = aliceDomain + ':' + str(alicePort) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     bobDir = baseDir + '/.tests/bob' | 
					
						
							|  |  |  |  |     bobDomain = '127.0.0.79' | 
					
						
							|  |  |  |  |     bobPort = 61936 | 
					
						
							|  |  |  |  |     bobSendThreads = [] | 
					
						
							|  |  |  |  |     bobAddress = bobDomain + ':' + str(bobPort) | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     global thrAlice | 
					
						
							|  |  |  |  |     if thrAlice: | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |         while thrAlice.is_alive(): | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |             thrAlice.stop() | 
					
						
							|  |  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |  |         thrAlice.kill() | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     thrAlice = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=createServerAlice, | 
					
						
							|  |  |  |  |                         args=(aliceDir, aliceDomain, alicePort, bobAddress, | 
					
						
							|  |  |  |  |                               federationList, False, False, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                               aliceSendThreads), | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                         daemon=True) | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |     global thrBob | 
					
						
							|  |  |  |  |     if thrBob: | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |         while thrBob.is_alive(): | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |             thrBob.stop() | 
					
						
							|  |  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |  |         thrBob.kill() | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     thrBob = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=createServerBob, | 
					
						
							|  |  |  |  |                         args=(bobDir, bobDomain, bobPort, aliceAddress, | 
					
						
							|  |  |  |  |                               federationList, False, False, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                               bobSendThreads), | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                         daemon=True) | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrAlice.start() | 
					
						
							|  |  |  |  |     thrBob.start() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrAlice.is_alive() is True | 
					
						
							|  |  |  |  |     assert thrBob.is_alive() is True | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # wait for all servers to be running | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     ctr = 0 | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  |     while not (testServerAliceRunning and testServerBobRunning): | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         ctr += 1 | 
					
						
							|  |  |  |  |         if ctr > 60: | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  |             break | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('Alice online: ' + str(testServerAliceRunning)) | 
					
						
							|  |  |  |  |     print('Bob online: ' + str(testServerBobRunning)) | 
					
						
							|  |  |  |  |     assert ctr <= 60 | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  |     time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # In the beginning all was calm and there were no follows | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     print('*********************************************************') | 
					
						
							|  |  |  |  |     print('Alice sends a follow request to Bob') | 
					
						
							|  |  |  |  |     os.chdir(aliceDir) | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     sessionAlice = createSession(proxyType) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     inReplyTo = None | 
					
						
							|  |  |  |  |     inReplyToAtomUri = None | 
					
						
							|  |  |  |  |     subject = None | 
					
						
							|  |  |  |  |     alicePostLog = [] | 
					
						
							|  |  |  |  |     followersOnly = False | 
					
						
							|  |  |  |  |     saveToFile = True | 
					
						
							|  |  |  |  |     clientToServer = False | 
					
						
							|  |  |  |  |     ccUrl = None | 
					
						
							|  |  |  |  |     alicePersonCache = {} | 
					
						
							|  |  |  |  |     aliceCachedWebfingers = {} | 
					
						
							|  |  |  |  |     alicePostLog = [] | 
					
						
							| 
									
										
										
										
											2021-02-09 19:02:10 +00:00
										 |  |  |  |     bobActor = httpPrefix + '://' + bobAddress + '/users/bob' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     sendResult = \ | 
					
						
							|  |  |  |  |         sendFollowRequest(sessionAlice, aliceDir, | 
					
						
							|  |  |  |  |                           'alice', aliceDomain, alicePort, httpPrefix, | 
					
						
							| 
									
										
										
										
											2021-02-09 19:02:10 +00:00
										 |  |  |  |                           'bob', bobDomain, bobActor, | 
					
						
							|  |  |  |  |                           bobPort, httpPrefix, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                           clientToServer, federationList, | 
					
						
							|  |  |  |  |                           aliceSendThreads, alicePostLog, | 
					
						
							|  |  |  |  |                           aliceCachedWebfingers, alicePersonCache, | 
					
						
							| 
									
										
										
										
											2020-12-26 10:22:56 +00:00
										 |  |  |  |                           True, __version__) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('sendResult: ' + str(sendResult)) | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-23 10:58:50 +00:00
										 |  |  |  |     for t in range(16): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         if os.path.isfile(bobDir + '/accounts/bob@' + | 
					
						
							|  |  |  |  |                           bobDomain + '/followers.txt'): | 
					
						
							|  |  |  |  |             if os.path.isfile(aliceDir + '/accounts/alice@' + | 
					
						
							|  |  |  |  |                               aliceDomain + '/following.txt'): | 
					
						
							| 
									
										
										
										
											2020-09-03 12:16:24 +00:00
										 |  |  |  |                 if os.path.isfile(aliceDir + '/accounts/alice@' + | 
					
						
							|  |  |  |  |                                   aliceDomain + '/followingCalendar.txt'): | 
					
						
							|  |  |  |  |                     break | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert validInbox(bobDir, 'bob', bobDomain) | 
					
						
							|  |  |  |  |     assert validInboxFilenames(bobDir, 'bob', bobDomain, | 
					
						
							|  |  |  |  |                                aliceDomain, alicePort) | 
					
						
							| 
									
										
										
										
											2020-09-03 12:16:24 +00:00
										 |  |  |  |     assert 'alice@' + aliceDomain in open(bobDir + '/accounts/bob@' + | 
					
						
							|  |  |  |  |                                           bobDomain + '/followers.txt').read() | 
					
						
							|  |  |  |  |     assert 'bob@' + bobDomain in open(aliceDir + '/accounts/alice@' + | 
					
						
							|  |  |  |  |                                       aliceDomain + '/following.txt').read() | 
					
						
							|  |  |  |  |     assert 'bob@' + bobDomain in open(aliceDir + '/accounts/alice@' + | 
					
						
							|  |  |  |  |                                       aliceDomain + | 
					
						
							|  |  |  |  |                                       '/followingCalendar.txt').read() | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     print('\n\n*********************************************************') | 
					
						
							|  |  |  |  |     print('Alice sends a message to Bob') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     alicePostLog = [] | 
					
						
							|  |  |  |  |     alicePersonCache = {} | 
					
						
							|  |  |  |  |     aliceCachedWebfingers = {} | 
					
						
							|  |  |  |  |     alicePostLog = [] | 
					
						
							|  |  |  |  |     isArticle = False | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     sendResult = \ | 
					
						
							|  |  |  |  |         sendPost(__version__, | 
					
						
							|  |  |  |  |                  sessionAlice, aliceDir, 'alice', aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                  'bob', bobDomain, bobPort, ccUrl, | 
					
						
							|  |  |  |  |                  httpPrefix, 'Alice message', followersOnly, saveToFile, | 
					
						
							| 
									
										
										
										
											2020-08-21 17:40:50 +00:00
										 |  |  |  |                  clientToServer, True, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                  None, None, None, city, federationList, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                  aliceSendThreads, alicePostLog, aliceCachedWebfingers, | 
					
						
							|  |  |  |  |                  alicePersonCache, isArticle, inReplyTo, | 
					
						
							|  |  |  |  |                  inReplyToAtomUri, subject) | 
					
						
							|  |  |  |  |     print('sendResult: ' + str(sendResult)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue' | 
					
						
							|  |  |  |  |     inboxPath = bobDir + '/accounts/bob@' + bobDomain + '/inbox' | 
					
						
							|  |  |  |  |     aliceMessageArrived = False | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  |     for i in range(20): | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  |         if os.path.isdir(inboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             if len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                     if os.path.isfile(os.path.join(inboxPath, name))]) > 0: | 
					
						
							|  |  |  |  |                 aliceMessageArrived = True | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  |                 print('Alice message sent to Bob!') | 
					
						
							|  |  |  |  |                 break | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert aliceMessageArrived is True | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  |     print('Message from Alice to Bob succeeded') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # stop the servers | 
					
						
							|  |  |  |  |     thrAlice.kill() | 
					
						
							|  |  |  |  |     thrAlice.join() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrAlice.is_alive() is False | 
					
						
							| 
									
										
										
										
											2019-10-15 09:31:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrBob.kill() | 
					
						
							|  |  |  |  |     thrBob.join() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrBob.is_alive() is False | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-09 08:52:53 +00:00
										 |  |  |  |     # queue item removed | 
					
						
							| 
									
										
										
										
											2019-11-09 21:39:04 +00:00
										 |  |  |  |     time.sleep(4) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len([name for name in os.listdir(queuePath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(queuePath, name))]) == 0 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     shutil.rmtree(baseDir + '/.tests') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 12:35:29 +00:00
										 |  |  |  | def testFollowersOfPerson(): | 
					
						
							|  |  |  |  |     print('testFollowersOfPerson') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     currDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'mxpop' | 
					
						
							|  |  |  |  |     domain = 'diva.domain' | 
					
						
							|  |  |  |  |     password = 'birb' | 
					
						
							|  |  |  |  |     port = 80 | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     federationList = [] | 
					
						
							|  |  |  |  |     baseDir = currDir + '/.tests_followersofperson' | 
					
						
							| 
									
										
										
										
											2019-07-05 12:35:29 +00:00
										 |  |  |  |     if os.path.isdir(baseDir): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  |     os.mkdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, nickname, domain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'maxboardroom', domain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'ultrapancake', domain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'drokk', domain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'sausagedog', domain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     clearFollows(baseDir, nickname, domain) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'maxboardroom', domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, 'drokk', domain, 'ultrapancake', domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							| 
									
										
										
										
											2019-07-05 12:35:29 +00:00
										 |  |  |  |     # deliberate duplication | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     followPerson(baseDir, 'drokk', domain, 'ultrapancake', domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, 'sausagedog', domain, 'ultrapancake', domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'ultrapancake', domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'someother', 'randodomain.net', | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     followList = getFollowersOfPerson(baseDir, 'ultrapancake', domain) | 
					
						
							|  |  |  |  |     assert len(followList) == 3 | 
					
						
							|  |  |  |  |     assert 'mxpop@' + domain in followList | 
					
						
							|  |  |  |  |     assert 'drokk@' + domain in followList | 
					
						
							|  |  |  |  |     assert 'sausagedog@' + domain in followList | 
					
						
							| 
									
										
										
										
											2019-07-05 12:35:29 +00:00
										 |  |  |  |     os.chdir(currDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(baseDir) | 
					
						
							| 
									
										
										
										
											2019-07-05 14:25:15 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 14:25:15 +00:00
										 |  |  |  | def testNoOfFollowersOnDomain(): | 
					
						
							|  |  |  |  |     print('testNoOfFollowersOnDomain') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     currDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'mxpop' | 
					
						
							|  |  |  |  |     domain = 'diva.domain' | 
					
						
							|  |  |  |  |     otherdomain = 'soup.dragon' | 
					
						
							|  |  |  |  |     password = 'birb' | 
					
						
							|  |  |  |  |     port = 80 | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     federationList = [] | 
					
						
							|  |  |  |  |     baseDir = currDir + '/.tests_nooffollowersOndomain' | 
					
						
							| 
									
										
										
										
											2019-07-05 14:25:15 +00:00
										 |  |  |  |     if os.path.isdir(baseDir): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  |     os.mkdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |     createPerson(baseDir, nickname, domain, port, httpPrefix, True, | 
					
						
							|  |  |  |  |                  False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'maxboardroom', otherdomain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'ultrapancake', otherdomain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'drokk', otherdomain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPerson(baseDir, 'sausagedog', otherdomain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                  httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     followPerson(baseDir, 'drokk', otherdomain, nickname, domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, 'sausagedog', otherdomain, nickname, domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, 'maxboardroom', otherdomain, nickname, domain, | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, | 
					
						
							|  |  |  |  |                      'cucumber', 'sandwiches.party', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, | 
					
						
							|  |  |  |  |                      'captainsensible', 'damned.zone', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'pilchard', 'zombies.attack', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'drokk', otherdomain, | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'sausagedog', otherdomain, | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'maxboardroom', otherdomain, | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     followersOnOtherDomain = \ | 
					
						
							|  |  |  |  |         noOfFollowersOnDomain(baseDir, nickname + '@' + domain, otherdomain) | 
					
						
							|  |  |  |  |     assert followersOnOtherDomain == 3 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  |     unfollowerOfAccount(baseDir, nickname, domain, 'sausagedog', otherdomain) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     followersOnOtherDomain = \ | 
					
						
							|  |  |  |  |         noOfFollowersOnDomain(baseDir, nickname + '@' + domain, otherdomain) | 
					
						
							|  |  |  |  |     assert followersOnOtherDomain == 2 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 14:25:15 +00:00
										 |  |  |  |     os.chdir(currDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-08 08:51:33 +00:00
										 |  |  |  | def testGroupFollowers(): | 
					
						
							|  |  |  |  |     print('testGroupFollowers') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     currDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'test735' | 
					
						
							|  |  |  |  |     domain = 'mydomain.com' | 
					
						
							|  |  |  |  |     password = 'somepass' | 
					
						
							|  |  |  |  |     port = 80 | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     federationList = [] | 
					
						
							|  |  |  |  |     baseDir = currDir + '/.tests_testgroupfollowers' | 
					
						
							| 
									
										
										
										
											2019-07-08 08:51:33 +00:00
										 |  |  |  |     if os.path.isdir(baseDir): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  |     os.mkdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |     createPerson(baseDir, nickname, domain, port, httpPrefix, True, | 
					
						
							|  |  |  |  |                  False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     clearFollowers(baseDir, nickname, domain) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'badger', 'wild.domain', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'squirrel', 'wild.domain', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'rodent', 'wild.domain', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'utterly', 'clutterly.domain', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'zonked', 'zzz.domain', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'nap', 'zzz.domain', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     grouped = groupFollowersByDomain(baseDir, nickname, domain) | 
					
						
							|  |  |  |  |     assert len(grouped.items()) == 3 | 
					
						
							| 
									
										
										
										
											2019-07-08 08:51:33 +00:00
										 |  |  |  |     assert grouped.get('zzz.domain') | 
					
						
							|  |  |  |  |     assert grouped.get('clutterly.domain') | 
					
						
							|  |  |  |  |     assert grouped.get('wild.domain') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len(grouped['zzz.domain']) == 2 | 
					
						
							|  |  |  |  |     assert len(grouped['wild.domain']) == 3 | 
					
						
							|  |  |  |  |     assert len(grouped['clutterly.domain']) == 1 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-08 08:51:33 +00:00
										 |  |  |  |     os.chdir(currDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 09:24:55 +00:00
										 |  |  |  | def testFollows(): | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  |     print('testFollows') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     currDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'test529' | 
					
						
							|  |  |  |  |     domain = 'testdomain.com' | 
					
						
							|  |  |  |  |     password = 'mypass' | 
					
						
							|  |  |  |  |     port = 80 | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     federationList = ['wild.com', 'mesh.com'] | 
					
						
							|  |  |  |  |     baseDir = currDir + '/.tests_testfollows' | 
					
						
							| 
									
										
										
										
											2019-07-03 09:24:55 +00:00
										 |  |  |  |     if os.path.isdir(baseDir): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  |     os.mkdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |     createPerson(baseDir, nickname, domain, port, httpPrefix, True, | 
					
						
							|  |  |  |  |                  False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     clearFollows(baseDir, nickname, domain) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'badger', 'wild.com', | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'squirrel', 'secret.com', | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'rodent', 'drainpipe.com', | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'batman', 'mesh.com', | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  |     followPerson(baseDir, nickname, domain, 'giraffe', 'trees.com', | 
					
						
							|  |  |  |  |                  federationList, False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     f = open(baseDir + '/accounts/' + nickname + '@' + domain + | 
					
						
							|  |  |  |  |              '/following.txt', "r") | 
					
						
							|  |  |  |  |     domainFound = False | 
					
						
							| 
									
										
										
										
											2019-07-03 09:24:55 +00:00
										 |  |  |  |     for followingDomain in f: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |  |         testDomain = followingDomain.split('@')[1] | 
					
						
							|  |  |  |  |         testDomain = testDomain.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         if testDomain == 'mesh.com': | 
					
						
							|  |  |  |  |             domainFound = True | 
					
						
							| 
									
										
										
										
											2019-07-03 09:24:55 +00:00
										 |  |  |  |         if testDomain not in federationList: | 
					
						
							|  |  |  |  |             print(testDomain) | 
					
						
							|  |  |  |  |             assert(False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 09:33:28 +00:00
										 |  |  |  |     assert(domainFound) | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  |     unfollowAccount(baseDir, nickname, domain, 'batman', 'mesh.com') | 
					
						
							| 
									
										
										
										
											2019-07-03 09:33:28 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     domainFound = False | 
					
						
							| 
									
										
										
										
											2019-07-03 09:33:28 +00:00
										 |  |  |  |     for followingDomain in f: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |  |         testDomain = followingDomain.split('@')[1] | 
					
						
							|  |  |  |  |         testDomain = testDomain.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         if testDomain == 'mesh.com': | 
					
						
							|  |  |  |  |             domainFound = True | 
					
						
							|  |  |  |  |     assert(domainFound is False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     clearFollowers(baseDir, nickname, domain) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'badger', 'wild.com', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'squirrel', 'secret.com', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'rodent', 'drainpipe.com', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'batman', 'mesh.com', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  |     followerOfPerson(baseDir, nickname, domain, 'giraffe', 'trees.com', | 
					
						
							|  |  |  |  |                      federationList, False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     f = open(baseDir + '/accounts/' + nickname + '@' + domain + | 
					
						
							|  |  |  |  |              '/followers.txt', "r") | 
					
						
							| 
									
										
										
										
											2019-07-03 09:24:55 +00:00
										 |  |  |  |     for followerDomain in f: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |  |         testDomain = followerDomain.split('@')[1] | 
					
						
							|  |  |  |  |         testDomain = testDomain.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2019-07-03 09:24:55 +00:00
										 |  |  |  |         if testDomain not in federationList: | 
					
						
							|  |  |  |  |             print(testDomain) | 
					
						
							|  |  |  |  |             assert(False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     os.chdir(currDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(baseDir) | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  | def testCreatePerson(): | 
					
						
							|  |  |  |  |     print('testCreatePerson') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     currDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'test382' | 
					
						
							|  |  |  |  |     domain = 'badgerdomain.com' | 
					
						
							|  |  |  |  |     password = 'mypass' | 
					
						
							|  |  |  |  |     port = 80 | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     clientToServer = False | 
					
						
							|  |  |  |  |     baseDir = currDir + '/.tests_createperson' | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  |     if os.path.isdir(baseDir): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  |     os.mkdir(baseDir) | 
					
						
							|  |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     privateKeyPem, publicKeyPem, person, wfEndpoint = \ | 
					
						
							|  |  |  |  |         createPerson(baseDir, nickname, domain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                      httpPrefix, True, False, password) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert os.path.isfile(baseDir + '/accounts/passwords') | 
					
						
							|  |  |  |  |     deleteAllPosts(baseDir, nickname, domain, 'inbox') | 
					
						
							|  |  |  |  |     deleteAllPosts(baseDir, nickname, domain, 'outbox') | 
					
						
							|  |  |  |  |     setDisplayNickname(baseDir, nickname, domain, 'badger') | 
					
						
							|  |  |  |  |     setBio(baseDir, nickname, domain, 'Randomly roaming in your backyard') | 
					
						
							| 
									
										
										
										
											2020-06-24 13:30:50 +00:00
										 |  |  |  |     archivePostsForPerson(nickname, domain, baseDir, 'inbox', None, {}, 4) | 
					
						
							|  |  |  |  |     archivePostsForPerson(nickname, domain, baseDir, 'outbox', None, {}, 4) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     createPublicPost(baseDir, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                      "G'day world!", False, True, clientToServer, | 
					
						
							| 
									
										
										
										
											2021-01-07 15:38:55 +00:00
										 |  |  |  |                      True, None, None, None, None, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |                      'Not suitable for Vogons', 'London, England') | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     os.chdir(currDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  | def testAuthentication(): | 
					
						
							|  |  |  |  |     print('testAuthentication') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     currDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'test8743' | 
					
						
							|  |  |  |  |     password = 'SuperSecretPassword12345' | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     baseDir = currDir + '/.tests_authentication' | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  |     if os.path.isdir(baseDir): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir) | 
					
						
							|  |  |  |  |     os.mkdir(baseDir) | 
					
						
							|  |  |  |  |     os.chdir(baseDir) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert storeBasicCredentials(baseDir, 'othernick', 'otherpass') | 
					
						
							|  |  |  |  |     assert storeBasicCredentials(baseDir, 'bad:nick', 'otherpass') is False | 
					
						
							|  |  |  |  |     assert storeBasicCredentials(baseDir, 'badnick', 'otherpa:ss') is False | 
					
						
							|  |  |  |  |     assert storeBasicCredentials(baseDir, nickname, password) | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     authHeader = createBasicAuthHeader(nickname, password) | 
					
						
							|  |  |  |  |     assert authorizeBasic(baseDir, '/users/' + nickname + '/inbox', | 
					
						
							|  |  |  |  |                           authHeader, False) | 
					
						
							|  |  |  |  |     assert authorizeBasic(baseDir, '/users/' + nickname, | 
					
						
							|  |  |  |  |                           authHeader, False) is False | 
					
						
							|  |  |  |  |     assert authorizeBasic(baseDir, '/users/othernick/inbox', | 
					
						
							|  |  |  |  |                           authHeader, False) is False | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     authHeader = createBasicAuthHeader(nickname, password + '1') | 
					
						
							|  |  |  |  |     assert authorizeBasic(baseDir, '/users/' + nickname + '/inbox', | 
					
						
							|  |  |  |  |                           authHeader, False) is False | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     password = 'someOtherPassword' | 
					
						
							|  |  |  |  |     assert storeBasicCredentials(baseDir, nickname, password) | 
					
						
							| 
									
										
										
										
											2019-07-03 19:13:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     authHeader = createBasicAuthHeader(nickname, password) | 
					
						
							|  |  |  |  |     assert authorizeBasic(baseDir, '/users/' + nickname + '/inbox', | 
					
						
							|  |  |  |  |                           authHeader, False) | 
					
						
							| 
									
										
										
										
											2019-07-03 19:13:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  |     os.chdir(currDir) | 
					
						
							|  |  |  |  |     shutil.rmtree(baseDir) | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | def testClientToServer(): | 
					
						
							|  |  |  |  |     print('Testing sending a post via c2s') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     global testServerAliceRunning | 
					
						
							|  |  |  |  |     global testServerBobRunning | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testServerAliceRunning = False | 
					
						
							|  |  |  |  |     testServerBobRunning = False | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     httpPrefix = 'http' | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     proxyType = None | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     federationList = [] | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     if os.path.isdir(baseDir + '/.tests'): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir + '/.tests') | 
					
						
							|  |  |  |  |     os.mkdir(baseDir + '/.tests') | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # create the servers | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     aliceDir = baseDir + '/.tests/alice' | 
					
						
							|  |  |  |  |     aliceDomain = '127.0.0.42' | 
					
						
							|  |  |  |  |     alicePort = 61935 | 
					
						
							|  |  |  |  |     aliceSendThreads = [] | 
					
						
							|  |  |  |  |     aliceAddress = aliceDomain + ':' + str(alicePort) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     bobDir = baseDir + '/.tests/bob' | 
					
						
							|  |  |  |  |     bobDomain = '127.0.0.64' | 
					
						
							|  |  |  |  |     bobPort = 61936 | 
					
						
							|  |  |  |  |     bobSendThreads = [] | 
					
						
							|  |  |  |  |     bobAddress = bobDomain + ':' + str(bobPort) | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     global thrAlice | 
					
						
							|  |  |  |  |     if thrAlice: | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |         while thrAlice.is_alive(): | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |             thrAlice.stop() | 
					
						
							|  |  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |  |         thrAlice.kill() | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     thrAlice = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=createServerAlice, | 
					
						
							|  |  |  |  |                         args=(aliceDir, aliceDomain, alicePort, bobAddress, | 
					
						
							|  |  |  |  |                               federationList, False, False, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                               aliceSendThreads), | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                         daemon=True) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |     global thrBob | 
					
						
							|  |  |  |  |     if thrBob: | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |         while thrBob.is_alive(): | 
					
						
							| 
									
										
										
										
											2020-02-19 12:27:21 +00:00
										 |  |  |  |             thrBob.stop() | 
					
						
							|  |  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |  |         thrBob.kill() | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     thrBob = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=createServerBob, | 
					
						
							|  |  |  |  |                         args=(bobDir, bobDomain, bobPort, aliceAddress, | 
					
						
							|  |  |  |  |                               federationList, False, False, | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |  |                               bobSendThreads), | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                         daemon=True) | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrAlice.start() | 
					
						
							|  |  |  |  |     thrBob.start() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrAlice.is_alive() is True | 
					
						
							|  |  |  |  |     assert thrBob.is_alive() is True | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # wait for both servers to be running | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     ctr = 0 | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  |     while not (testServerAliceRunning and testServerBobRunning): | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         ctr += 1 | 
					
						
							|  |  |  |  |         if ctr > 60: | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  |             break | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('Alice online: ' + str(testServerAliceRunning)) | 
					
						
							|  |  |  |  |     print('Bob online: ' + str(testServerBobRunning)) | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     time.sleep(1) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  |     print('\n\n*******************************************************') | 
					
						
							|  |  |  |  |     print('Alice sends to Bob via c2s') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     sessionAlice = createSession(proxyType) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     followersOnly = False | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |  |     attachedImageFilename = baseDir + '/img/logo.png' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     mediaType = getAttachmentMediaType(attachedImageFilename) | 
					
						
							|  |  |  |  |     attachedImageDescription = 'Logo' | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     isArticle = False | 
					
						
							|  |  |  |  |     cachedWebfingers = {} | 
					
						
							|  |  |  |  |     personCache = {} | 
					
						
							|  |  |  |  |     password = 'alicepass' | 
					
						
							|  |  |  |  |     outboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/outbox' | 
					
						
							|  |  |  |  |     inboxPath = bobDir + '/accounts/bob@' + bobDomain + '/inbox' | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 0 | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) == 0 | 
					
						
							|  |  |  |  |     sendResult = \ | 
					
						
							|  |  |  |  |         sendPostViaServer(__version__, | 
					
						
							|  |  |  |  |                           aliceDir, sessionAlice, 'alice', password, | 
					
						
							|  |  |  |  |                           aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                           'bob', bobDomain, bobPort, None, | 
					
						
							|  |  |  |  |                           httpPrefix, 'Sent from my ActivityPub client', | 
					
						
							| 
									
										
										
										
											2020-08-21 17:40:50 +00:00
										 |  |  |  |                           followersOnly, True, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                           attachedImageFilename, mediaType, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                           attachedImageDescription, city, | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                           cachedWebfingers, personCache, isArticle, | 
					
						
							|  |  |  |  |                           True, None, None, None) | 
					
						
							|  |  |  |  |     print('sendResult: ' + str(sendResult)) | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     for i in range(30): | 
					
						
							|  |  |  |  |         if os.path.isdir(outboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             if len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                     if os.path.isfile(os.path.join(outboxPath, name))]) == 1: | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  |                 break | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 1 | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  |     print(">>> c2s post arrived in Alice's outbox") | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  |     for i in range(30): | 
					
						
							|  |  |  |  |         if os.path.isdir(inboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             if len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                     if os.path.isfile(os.path.join(inboxPath, name))]) == 1: | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  |                 break | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) == 1 | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  |     print(">>> s2s post arrived in Bob's inbox") | 
					
						
							|  |  |  |  |     print("c2s send success") | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |  |     print('\n\nGetting message id for the post') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     statusNumber = 0 | 
					
						
							|  |  |  |  |     outboxPostFilename = None | 
					
						
							|  |  |  |  |     outboxPostId = None | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |  |     for name in os.listdir(outboxPath): | 
					
						
							|  |  |  |  |         if '#statuses#' in name: | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             statusNumber = name.split('#statuses#')[1].replace('.json', '') | 
					
						
							|  |  |  |  |             statusNumber = int(statusNumber.replace('#activity', '')) | 
					
						
							|  |  |  |  |             outboxPostFilename = outboxPath + '/' + name | 
					
						
							|  |  |  |  |             postJsonObject = loadJson(outboxPostFilename, 0) | 
					
						
							| 
									
										
										
										
											2019-11-23 10:08:00 +00:00
										 |  |  |  |             if postJsonObject: | 
					
						
							| 
									
										
										
										
											2020-08-23 11:13:35 +00:00
										 |  |  |  |                 outboxPostId = removeIdEnding(postJsonObject['id']) | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |  |     assert outboxPostId | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('message id obtained: ' + outboxPostId) | 
					
						
							|  |  |  |  |     assert validInbox(bobDir, 'bob', bobDomain) | 
					
						
							|  |  |  |  |     assert validInboxFilenames(bobDir, 'bob', bobDomain, | 
					
						
							|  |  |  |  |                                aliceDomain, alicePort) | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     print('\n\nAlice follows Bob') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     sendFollowRequestViaServer(aliceDir, sessionAlice, | 
					
						
							|  |  |  |  |                                'alice', password, | 
					
						
							|  |  |  |  |                                aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                                'bob', bobDomain, bobPort, | 
					
						
							|  |  |  |  |                                httpPrefix, | 
					
						
							|  |  |  |  |                                cachedWebfingers, personCache, | 
					
						
							|  |  |  |  |                                True, __version__) | 
					
						
							| 
									
										
										
										
											2020-11-23 15:07:55 +00:00
										 |  |  |  |     alicePetnamesFilename = aliceDir + '/accounts/' + \ | 
					
						
							|  |  |  |  |         'alice@' + aliceDomain + '/petnames.txt' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     aliceFollowingFilename = \ | 
					
						
							|  |  |  |  |         aliceDir + '/accounts/alice@' + aliceDomain + '/following.txt' | 
					
						
							|  |  |  |  |     bobFollowersFilename = \ | 
					
						
							|  |  |  |  |         bobDir + '/accounts/bob@' + bobDomain + '/followers.txt' | 
					
						
							| 
									
										
										
										
											2020-03-02 21:28:22 +00:00
										 |  |  |  |     for t in range(10): | 
					
						
							|  |  |  |  |         if os.path.isfile(bobFollowersFilename): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             if 'alice@' + aliceDomain + ':' + str(alicePort) in \ | 
					
						
							|  |  |  |  |                open(bobFollowersFilename).read(): | 
					
						
							| 
									
										
										
										
											2020-11-23 15:07:55 +00:00
										 |  |  |  |                 if os.path.isfile(aliceFollowingFilename) and \ | 
					
						
							|  |  |  |  |                    os.path.isfile(alicePetnamesFilename): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                     if 'bob@' + bobDomain + ':' + str(bobPort) in \ | 
					
						
							|  |  |  |  |                        open(aliceFollowingFilename).read(): | 
					
						
							| 
									
										
										
										
											2019-07-17 11:24:11 +00:00
										 |  |  |  |                         break | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-02 21:28:22 +00:00
										 |  |  |  |     assert os.path.isfile(bobFollowersFilename) | 
					
						
							|  |  |  |  |     assert os.path.isfile(aliceFollowingFilename) | 
					
						
							| 
									
										
										
										
											2020-11-23 15:07:55 +00:00
										 |  |  |  |     assert os.path.isfile(alicePetnamesFilename) | 
					
						
							|  |  |  |  |     assert 'bob bob@' + bobDomain in \ | 
					
						
							|  |  |  |  |         open(alicePetnamesFilename).read() | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print('alice@' + aliceDomain + ':' + str(alicePort) + ' in ' + | 
					
						
							|  |  |  |  |           bobFollowersFilename) | 
					
						
							|  |  |  |  |     assert 'alice@' + aliceDomain + ':' + str(alicePort) in \ | 
					
						
							|  |  |  |  |         open(bobFollowersFilename).read() | 
					
						
							|  |  |  |  |     print('bob@' + bobDomain + ':' + str(bobPort) + ' in ' + | 
					
						
							|  |  |  |  |           aliceFollowingFilename) | 
					
						
							|  |  |  |  |     assert 'bob@' + bobDomain + ':' + str(bobPort) in \ | 
					
						
							|  |  |  |  |         open(aliceFollowingFilename).read() | 
					
						
							|  |  |  |  |     assert validInbox(bobDir, 'bob', bobDomain) | 
					
						
							|  |  |  |  |     assert validInboxFilenames(bobDir, 'bob', bobDomain, | 
					
						
							|  |  |  |  |                                aliceDomain, alicePort) | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     print('\n\nBob follows Alice') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     sendFollowRequestViaServer(aliceDir, sessionAlice, | 
					
						
							|  |  |  |  |                                'bob', 'bobpass', | 
					
						
							|  |  |  |  |                                bobDomain, bobPort, | 
					
						
							|  |  |  |  |                                'alice', aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                                httpPrefix, | 
					
						
							|  |  |  |  |                                cachedWebfingers, personCache, | 
					
						
							|  |  |  |  |                                True, __version__) | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |  |     for t in range(10): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         if os.path.isfile(aliceDir + '/accounts/alice@' + aliceDomain + | 
					
						
							|  |  |  |  |                           '/followers.txt'): | 
					
						
							|  |  |  |  |             if 'bob@' + bobDomain + ':' + str(bobPort) in \ | 
					
						
							|  |  |  |  |                open(aliceDir + '/accounts/alice@' + aliceDomain + | 
					
						
							|  |  |  |  |                     '/followers.txt').read(): | 
					
						
							|  |  |  |  |                 if os.path.isfile(bobDir + '/accounts/bob@' + bobDomain + | 
					
						
							|  |  |  |  |                                   '/following.txt'): | 
					
						
							| 
									
										
										
										
											2020-07-03 21:56:38 +00:00
										 |  |  |  |                     aliceHandleStr = \ | 
					
						
							|  |  |  |  |                         'alice@' + aliceDomain + ':' + str(alicePort) | 
					
						
							|  |  |  |  |                     if aliceHandleStr in \ | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |                        open(bobDir + '/accounts/bob@' + bobDomain + | 
					
						
							|  |  |  |  |                             '/following.txt').read(): | 
					
						
							| 
									
										
										
										
											2020-07-03 21:56:38 +00:00
										 |  |  |  |                         if os.path.isfile(bobDir + '/accounts/bob@' + | 
					
						
							|  |  |  |  |                                           bobDomain + | 
					
						
							|  |  |  |  |                                           '/followingCalendar.txt'): | 
					
						
							|  |  |  |  |                             if aliceHandleStr in \ | 
					
						
							|  |  |  |  |                                open(bobDir + '/accounts/bob@' + bobDomain + | 
					
						
							|  |  |  |  |                                     '/followingCalendar.txt').read(): | 
					
						
							|  |  |  |  |                                 break | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert os.path.isfile(aliceDir + '/accounts/alice@' + aliceDomain + | 
					
						
							|  |  |  |  |                           '/followers.txt') | 
					
						
							|  |  |  |  |     assert os.path.isfile(bobDir + '/accounts/bob@' + bobDomain + | 
					
						
							|  |  |  |  |                           '/following.txt') | 
					
						
							|  |  |  |  |     assert 'bob@' + bobDomain + ':' + str(bobPort) in \ | 
					
						
							|  |  |  |  |         open(aliceDir + '/accounts/alice@' + aliceDomain + | 
					
						
							|  |  |  |  |              '/followers.txt').read() | 
					
						
							|  |  |  |  |     assert 'alice@' + aliceDomain + ':' + str(alicePort) in \ | 
					
						
							|  |  |  |  |         open(bobDir + '/accounts/bob@' + bobDomain + '/following.txt').read() | 
					
						
							| 
									
										
										
										
											2019-07-18 09:26:47 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     print('\n\nBob likes the post') | 
					
						
							| 
									
										
										
										
											2020-06-09 11:03:59 +00:00
										 |  |  |  |     sessionBob = createSession(proxyType) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     password = 'bobpass' | 
					
						
							|  |  |  |  |     outboxPath = bobDir + '/accounts/bob@' + bobDomain + '/outbox' | 
					
						
							|  |  |  |  |     inboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/inbox' | 
					
						
							|  |  |  |  |     print(str(len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                    if os.path.isfile(os.path.join(outboxPath, name))]))) | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 1 | 
					
						
							|  |  |  |  |     print(str(len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                    if os.path.isfile(os.path.join(inboxPath, name))]))) | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) == 1 | 
					
						
							|  |  |  |  |     sendLikeViaServer(bobDir, sessionBob, | 
					
						
							|  |  |  |  |                       'bob', 'bobpass', | 
					
						
							|  |  |  |  |                       bobDomain, bobPort, | 
					
						
							|  |  |  |  |                       httpPrefix, outboxPostId, | 
					
						
							|  |  |  |  |                       cachedWebfingers, personCache, | 
					
						
							|  |  |  |  |                       True, __version__) | 
					
						
							| 
									
										
										
										
											2019-07-18 09:26:47 +00:00
										 |  |  |  |     for i in range(20): | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |         if os.path.isdir(outboxPath) and os.path.isdir(inboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             if len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                     if os.path.isfile(os.path.join(outboxPath, name))]) == 2: | 
					
						
							|  |  |  |  |                 test = len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                             if os.path.isfile(os.path.join(inboxPath, name))]) | 
					
						
							|  |  |  |  |                 if test == 1: | 
					
						
							| 
									
										
										
										
											2019-07-18 09:26:47 +00:00
										 |  |  |  |                     break | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 2 | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) == 1 | 
					
						
							| 
									
										
										
										
											2019-07-18 09:26:47 +00:00
										 |  |  |  |     print('Post liked') | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 09:26:47 +00:00
										 |  |  |  |     print('\n\nBob repeats the post') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     print(str(len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                    if os.path.isfile(os.path.join(outboxPath, name))]))) | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 2 | 
					
						
							|  |  |  |  |     print(str(len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                    if os.path.isfile(os.path.join(inboxPath, name))]))) | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) == 1 | 
					
						
							|  |  |  |  |     sendAnnounceViaServer(bobDir, sessionBob, 'bob', password, | 
					
						
							|  |  |  |  |                           bobDomain, bobPort, | 
					
						
							|  |  |  |  |                           httpPrefix, outboxPostId, | 
					
						
							|  |  |  |  |                           cachedWebfingers, | 
					
						
							|  |  |  |  |                           personCache, True, __version__) | 
					
						
							| 
									
										
										
										
											2019-07-16 22:57:45 +00:00
										 |  |  |  |     for i in range(20): | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |         if os.path.isdir(outboxPath) and os.path.isdir(inboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             if len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                     if os.path.isfile(os.path.join(outboxPath, name))]) == 3: | 
					
						
							|  |  |  |  |                 if len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                         if os.path.isfile(os.path.join(inboxPath, | 
					
						
							|  |  |  |  |                                                        name))]) == 2: | 
					
						
							| 
									
										
										
										
											2019-07-16 22:57:45 +00:00
										 |  |  |  |                     break | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 3 | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) == 2 | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |  |     print('Post repeated') | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     inboxPath = bobDir + '/accounts/bob@' + bobDomain + '/inbox' | 
					
						
							|  |  |  |  |     outboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/outbox' | 
					
						
							|  |  |  |  |     postsBefore = \ | 
					
						
							|  |  |  |  |         len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |              if os.path.isfile(os.path.join(inboxPath, name))]) | 
					
						
							|  |  |  |  |     print('\n\nAlice deletes her post: ' + outboxPostId + ' ' + | 
					
						
							|  |  |  |  |           str(postsBefore)) | 
					
						
							|  |  |  |  |     password = 'alicepass' | 
					
						
							|  |  |  |  |     sendDeleteViaServer(aliceDir, sessionAlice, 'alice', password, | 
					
						
							|  |  |  |  |                         aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                         httpPrefix, outboxPostId, | 
					
						
							|  |  |  |  |                         cachedWebfingers, personCache, | 
					
						
							|  |  |  |  |                         True, __version__) | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |  |     for i in range(30): | 
					
						
							|  |  |  |  |         if os.path.isdir(inboxPath): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |             test = len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                         if os.path.isfile(os.path.join(inboxPath, name))]) | 
					
						
							|  |  |  |  |             if test == postsBefore-1: | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |  |                 break | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     test = len([name for name in os.listdir(inboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(inboxPath, name))]) | 
					
						
							|  |  |  |  |     assert test == postsBefore - 1 | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |  |     print(">>> post deleted from Alice's outbox and Bob's inbox") | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert validInbox(bobDir, 'bob', bobDomain) | 
					
						
							|  |  |  |  |     assert validInboxFilenames(bobDir, 'bob', bobDomain, | 
					
						
							|  |  |  |  |                                aliceDomain, alicePort) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |  |     print('\n\nAlice unfollows Bob') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     password = 'alicepass' | 
					
						
							|  |  |  |  |     sendUnfollowRequestViaServer(baseDir, sessionAlice, | 
					
						
							|  |  |  |  |                                  'alice', password, | 
					
						
							|  |  |  |  |                                  aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                                  'bob', bobDomain, bobPort, | 
					
						
							|  |  |  |  |                                  httpPrefix, | 
					
						
							|  |  |  |  |                                  cachedWebfingers, personCache, | 
					
						
							|  |  |  |  |                                  True, __version__) | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |  |     for t in range(10): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         if 'alice@' + aliceDomain + ':' + str(alicePort) not in \ | 
					
						
							|  |  |  |  |            open(bobFollowersFilename).read(): | 
					
						
							|  |  |  |  |             if 'bob@' + bobDomain + ':' + str(bobPort) not in \ | 
					
						
							|  |  |  |  |                open(aliceFollowingFilename).read(): | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |  |                 break | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-02 21:28:22 +00:00
										 |  |  |  |     assert os.path.isfile(bobFollowersFilename) | 
					
						
							|  |  |  |  |     assert os.path.isfile(aliceFollowingFilename) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert 'alice@' + aliceDomain + ':' + str(alicePort) \ | 
					
						
							|  |  |  |  |         not in open(bobFollowersFilename).read() | 
					
						
							|  |  |  |  |     assert 'bob@' + bobDomain + ':' + str(bobPort) \ | 
					
						
							|  |  |  |  |         not in open(aliceFollowingFilename).read() | 
					
						
							|  |  |  |  |     assert validInbox(bobDir, 'bob', bobDomain) | 
					
						
							|  |  |  |  |     assert validInboxFilenames(bobDir, 'bob', bobDomain, | 
					
						
							|  |  |  |  |                                aliceDomain, alicePort) | 
					
						
							|  |  |  |  |     assert validInbox(aliceDir, 'alice', aliceDomain) | 
					
						
							|  |  |  |  |     assert validInboxFilenames(aliceDir, 'alice', aliceDomain, | 
					
						
							|  |  |  |  |                                bobDomain, bobPort) | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  |     # stop the servers | 
					
						
							|  |  |  |  |     thrAlice.kill() | 
					
						
							|  |  |  |  |     thrAlice.join() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrAlice.is_alive() is False | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrBob.kill() | 
					
						
							|  |  |  |  |     thrBob.join() | 
					
						
							| 
									
										
										
										
											2020-12-18 15:29:12 +00:00
										 |  |  |  |     assert thrBob.is_alive() is False | 
					
						
							| 
									
										
										
										
											2019-07-16 11:33:40 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     # shutil.rmtree(aliceDir) | 
					
						
							|  |  |  |  |     # shutil.rmtree(bobDir) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 16:35:46 +00:00
										 |  |  |  | def testActorParsing(): | 
					
						
							|  |  |  |  |     print('testActorParsing') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     actor = 'https://mydomain:72/users/mynick' | 
					
						
							|  |  |  |  |     domain, port = getDomainFromActor(actor) | 
					
						
							|  |  |  |  |     assert domain == 'mydomain' | 
					
						
							|  |  |  |  |     assert port == 72 | 
					
						
							|  |  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |  |     assert nickname == 'mynick' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 16:41:02 +00:00
										 |  |  |  |     actor = 'https://element/accounts/badger' | 
					
						
							|  |  |  |  |     domain, port = getDomainFromActor(actor) | 
					
						
							|  |  |  |  |     assert domain == 'element' | 
					
						
							|  |  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |  |     assert nickname == 'badger' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     actor = 'egg@chicken.com' | 
					
						
							|  |  |  |  |     domain, port = getDomainFromActor(actor) | 
					
						
							|  |  |  |  |     assert domain == 'chicken.com' | 
					
						
							|  |  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |  |     assert nickname == 'egg' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     actor = '@waffle@cardboard' | 
					
						
							|  |  |  |  |     domain, port = getDomainFromActor(actor) | 
					
						
							|  |  |  |  |     assert domain == 'cardboard' | 
					
						
							|  |  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |  |     assert nickname == 'waffle' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     actor = 'https://astral/channel/sky' | 
					
						
							|  |  |  |  |     domain, port = getDomainFromActor(actor) | 
					
						
							|  |  |  |  |     assert domain == 'astral' | 
					
						
							|  |  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |  |     assert nickname == 'sky' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     actor = 'https://randomain/users/rando' | 
					
						
							|  |  |  |  |     domain, port = getDomainFromActor(actor) | 
					
						
							|  |  |  |  |     assert domain == 'randomain' | 
					
						
							|  |  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |  |     assert nickname == 'rando' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     actor = 'https://otherdomain:49/@othernick' | 
					
						
							|  |  |  |  |     domain, port = getDomainFromActor(actor) | 
					
						
							|  |  |  |  |     assert domain == 'otherdomain' | 
					
						
							|  |  |  |  |     assert port == 49 | 
					
						
							|  |  |  |  |     nickname = getNicknameFromActor(actor) | 
					
						
							|  |  |  |  |     assert nickname == 'othernick' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 16:35:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 08:55:05 +00:00
										 |  |  |  | def testWebLinks(): | 
					
						
							| 
									
										
										
										
											2019-09-01 08:57:51 +00:00
										 |  |  |  |     print('testWebLinks') | 
					
						
							| 
									
										
										
										
											2020-01-24 10:52:59 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-17 21:17:27 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         "<p>Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + \ | 
					
						
							|  |  |  |  |         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + \ | 
					
						
							|  |  |  |  |         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + \ | 
					
						
							|  |  |  |  |         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + \ | 
					
						
							|  |  |  |  |         " <a href=\"https://domain.ugh/tags/turbot\" class=\"mention " + \ | 
					
						
							|  |  |  |  |         "hashtag\" rel=\"tag\">#<span>turbot</span></a> <a href=\"" + \ | 
					
						
							|  |  |  |  |         "https://domain.ugh/tags/haddock\" class=\"mention hashtag\"" + \ | 
					
						
							|  |  |  |  |         " rel=\"tag\">#<span>haddock</span></a></p>" | 
					
						
							|  |  |  |  |     resultText = removeLongWords(exampleText, 40, []) | 
					
						
							|  |  |  |  |     assert resultText == "<p>Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + \ | 
					
						
							|  |  |  |  |         " <a href=\"https://domain.ugh/tags/turbot\" class=\"mention " + \ | 
					
						
							|  |  |  |  |         "hashtag\" rel=\"tag\">#<span>turbot</span></a> " + \ | 
					
						
							|  |  |  |  |         "<a href=\"https://domain.ugh/tags/haddock\" " + \ | 
					
						
							|  |  |  |  |         "class=\"mention hashtag\" rel=\"tag\">#<span>haddock</span></a></p>" | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         '<p><span class=\"h-card\"><a href=\"https://something/@orother' + \ | 
					
						
							|  |  |  |  |         '\" class=\"u-url mention\">@<span>foo</span></a></span> Some ' + \ | 
					
						
							|  |  |  |  |         'random text.</p><p>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + \ | 
					
						
							|  |  |  |  |         'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + \ | 
					
						
							|  |  |  |  |         'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + \ | 
					
						
							|  |  |  |  |         'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + \ | 
					
						
							|  |  |  |  |         'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + \ | 
					
						
							|  |  |  |  |         'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</p>' | 
					
						
							|  |  |  |  |     resultText = removeLongWords(exampleText, 40, []) | 
					
						
							|  |  |  |  |     assert resultText == \ | 
					
						
							|  |  |  |  |         '<p><span class="h-card"><a href="https://something/@orother"' + \ | 
					
						
							|  |  |  |  |         ' class="u-url mention">@<span>foo</span></a></span> ' + \ | 
					
						
							|  |  |  |  |         'Some random text.</p>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         'This post has a web links https://somesite.net\n\nAnd some other text' | 
					
						
							|  |  |  |  |     linkedText = addWebLinks(exampleText) | 
					
						
							|  |  |  |  |     assert \ | 
					
						
							| 
									
										
										
										
											2020-12-13 11:31:16 +00:00
										 |  |  |  |         '<a href="https://somesite.net" rel="nofollow noopener noreferrer"' + \ | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         ' target="_blank"><span class="invisible">https://' + \ | 
					
						
							|  |  |  |  |         '</span><span class="ellipsis">somesite.net</span></a' in linkedText | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         'This post has a very long web link\n\nhttp://' + \ | 
					
						
							|  |  |  |  |         'cbwebewuvfuftdiudbqd33dddbbyuef23fyug3bfhcyu2fct2' + \ | 
					
						
							|  |  |  |  |         'cuyqbcbucuwvckiwyfgewfvqejbchevbhwevuevwbqebqekve' + \ | 
					
						
							|  |  |  |  |         'qvuvjfkf.onion\n\nAnd some other text' | 
					
						
							|  |  |  |  |     linkedText = addWebLinks(exampleText) | 
					
						
							| 
									
										
										
										
											2019-10-01 10:36:51 +00:00
										 |  |  |  |     assert 'ellipsis' in linkedText | 
					
						
							| 
									
										
										
										
											2020-01-24 10:52:59 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         '<p>1. HAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAH' + \ | 
					
						
							|  |  |  |  |         'AHAHAHHAHAHAHAHAHAHAHAHAHAHAHAHHAHAHAHAHAHAHAHAH</p>' | 
					
						
							|  |  |  |  |     resultText = removeLongWords(exampleText, 40, []) | 
					
						
							|  |  |  |  |     assert resultText == '<p>1. HAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHA</p>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         '<p>Tox address is 88AB9DED6F9FBEF43E105FB72060A2D89F9B93C74' + \ | 
					
						
							|  |  |  |  |         '4E8C45AB3C5E42C361C837155AFCFD9D448 </p>' | 
					
						
							|  |  |  |  |     resultText = removeLongWords(exampleText, 40, []) | 
					
						
							|  |  |  |  |     assert resultText == exampleText | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-31 23:10:38 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         'some.incredibly.long.and.annoying.word.which.should.be.removed: ' + \ | 
					
						
							|  |  |  |  |         'The remaining text' | 
					
						
							|  |  |  |  |     resultText = removeLongWords(exampleText, 40, []) | 
					
						
							|  |  |  |  |     assert resultText == \ | 
					
						
							|  |  |  |  |         'some.incredibly.long.and.annoying.word.w\n' + \ | 
					
						
							|  |  |  |  |         'hich.should.be.removed: The remaining text' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         '<p>Tox address is 88AB9DED6F9FBEF43E105FB72060A2D89F9B93C74' + \ | 
					
						
							|  |  |  |  |         '4E8C45AB3C5E42C361C837155AFCFD9D448</p>' | 
					
						
							|  |  |  |  |     resultText = removeLongWords(exampleText, 40, []) | 
					
						
							|  |  |  |  |     assert resultText == \ | 
					
						
							|  |  |  |  |         '<p>Tox address is 88AB9DED6F9FBEF43E105FB72060A2D89F9B93C7\n' + \ | 
					
						
							|  |  |  |  |         '44E8C45AB3C5E42C361C837155AFCFD9D448</p>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         '<p>ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCA' + \ | 
					
						
							|  |  |  |  |         'BCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB' + \ | 
					
						
							|  |  |  |  |         'CABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC' + \ | 
					
						
							|  |  |  |  |         'ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCA' + \ | 
					
						
							|  |  |  |  |         'BCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB' + \ | 
					
						
							|  |  |  |  |         'CABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC' + \ | 
					
						
							|  |  |  |  |         'ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCA' + \ | 
					
						
							|  |  |  |  |         'BCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB' + \ | 
					
						
							|  |  |  |  |         'CABCABCABCABCABCABCABCABC</p>' | 
					
						
							|  |  |  |  |     resultText = removeLongWords(exampleText, 40, []) | 
					
						
							|  |  |  |  |     assert resultText == r'<p>ABCABCABCABCABCABCABCABCABCABCABCABCABCA<\p>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         '"the nucleus of mutual-support institutions, habits, and customs ' + \ | 
					
						
							|  |  |  |  |         'remains alive with the millions; it keeps them together; and ' + \ | 
					
						
							|  |  |  |  |         'they prefer to cling to their customs, beliefs, and traditions ' + \ | 
					
						
							|  |  |  |  |         'rather than to accept the teachings of a war of each ' + \ | 
					
						
							|  |  |  |  |         'against all"\n\n--Peter Kropotkin' | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |     testFnStr = addWebLinks(exampleText) | 
					
						
							|  |  |  |  |     resultText = removeLongWords(testFnStr, 40, []) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert resultText == exampleText | 
					
						
							| 
									
										
										
										
											2020-03-29 10:48:31 +00:00
										 |  |  |  |     assert 'ellipsis' not in resultText | 
					
						
							| 
									
										
										
										
											2020-03-29 09:59:54 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-12 09:34:58 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							|  |  |  |  |         '<p>filepopout=' + \ | 
					
						
							| 
									
										
										
										
											2020-05-12 09:42:24 +00:00
										 |  |  |  |         'TemplateAttachmentRichPopout<<\\p>' | 
					
						
							| 
									
										
										
										
											2020-05-12 09:34:58 +00:00
										 |  |  |  |     resultText = replaceContentDuplicates(exampleText) | 
					
						
							|  |  |  |  |     assert resultText == \ | 
					
						
							|  |  |  |  |         '<p>filepopout=' + \ | 
					
						
							|  |  |  |  |         'TemplateAttachmentRichPopout' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-07 20:51:34 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							| 
									
										
										
										
											2020-08-11 17:18:22 +00:00
										 |  |  |  |         '<p>Test1 test2 #YetAnotherExcessivelyLongwindedAndBoringHashtag</p>' | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |     testFnStr = addWebLinks(exampleText) | 
					
						
							|  |  |  |  |     resultText = removeLongWords(testFnStr, 40, []) | 
					
						
							| 
									
										
										
										
											2020-08-07 20:51:34 +00:00
										 |  |  |  |     assert(resultText == | 
					
						
							|  |  |  |  |            '<p>Test1 test2 ' | 
					
						
							|  |  |  |  |            '#YetAnotherExcessivelyLongwindedAndBorin\ngHashtag</p>') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-06 10:18:41 +00:00
										 |  |  |  |     exampleText = \ | 
					
						
							| 
									
										
										
										
											2020-12-06 14:47:06 +00:00
										 |  |  |  |         "<p>Don't remove a p2p link " + \ | 
					
						
							|  |  |  |  |         "rad:git:hwd1yrerc3mcgn8ga9rho3dqi4w33nep7kxmqezss4topyfgmexihp" + \ | 
					
						
							|  |  |  |  |         "33xcw</p>" | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |     testFnStr = addWebLinks(exampleText) | 
					
						
							|  |  |  |  |     resultText = removeLongWords(testFnStr, 40, []) | 
					
						
							| 
									
										
										
										
											2020-12-06 10:18:41 +00:00
										 |  |  |  |     assert resultText == exampleText | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-24 10:52:59 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-21 15:09:31 +00:00
										 |  |  |  | def testAddEmoji(): | 
					
						
							|  |  |  |  |     print('testAddEmoji') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     content = "Emoji :lemon: :strawberry: :banana:" | 
					
						
							|  |  |  |  |     httpPrefix = 'http' | 
					
						
							|  |  |  |  |     nickname = 'testuser' | 
					
						
							|  |  |  |  |     domain = 'testdomain.net' | 
					
						
							|  |  |  |  |     port = 3682 | 
					
						
							|  |  |  |  |     recipients = [] | 
					
						
							|  |  |  |  |     hashtags = {} | 
					
						
							|  |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     baseDirOriginal = os.getcwd() | 
					
						
							|  |  |  |  |     path = baseDir + '/.tests' | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  |     if not os.path.isdir(path): | 
					
						
							|  |  |  |  |         os.mkdir(path) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     path = baseDir + '/.tests/emoji' | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  |     if os.path.isdir(path): | 
					
						
							|  |  |  |  |         shutil.rmtree(path) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     os.mkdir(path) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     baseDir = path | 
					
						
							|  |  |  |  |     path = baseDir + '/emoji' | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  |     if os.path.isdir(path): | 
					
						
							|  |  |  |  |         shutil.rmtree(path) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     os.mkdir(path) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     copytree(baseDirOriginal + '/emoji', baseDir + '/emoji') | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  |     os.chdir(baseDir) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     privateKeyPem, publicKeyPem, person, wfEndpoint = \ | 
					
						
							|  |  |  |  |         createPerson(baseDir, nickname, domain, port, | 
					
						
							| 
									
										
										
										
											2020-07-12 12:31:28 +00:00
										 |  |  |  |                      httpPrefix, True, False, 'password') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     contentModified = \ | 
					
						
							|  |  |  |  |         addHtmlTags(baseDir, httpPrefix, | 
					
						
							|  |  |  |  |                     nickname, domain, content, | 
					
						
							|  |  |  |  |                     recipients, hashtags, True) | 
					
						
							| 
									
										
										
										
											2020-02-21 15:09:31 +00:00
										 |  |  |  |     assert ':lemon:' in contentModified | 
					
						
							| 
									
										
										
										
											2020-02-21 09:53:36 +00:00
										 |  |  |  |     assert contentModified.startswith('<p>') | 
					
						
							|  |  |  |  |     assert contentModified.endswith('</p>') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     tags = [] | 
					
						
							|  |  |  |  |     for tagName, tag in hashtags.items(): | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  |         tags.append(tag) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     content = contentModified | 
					
						
							|  |  |  |  |     contentModified = replaceEmojiFromTags(content, tags, 'content') | 
					
						
							|  |  |  |  |     # print('contentModified: '+contentModified) | 
					
						
							|  |  |  |  |     assert contentModified == '<p>Emoji 🍋 🍓 🍌</p>' | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     os.chdir(baseDirOriginal) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     shutil.rmtree(baseDirOriginal + '/.tests') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 18:48:34 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 12:45:53 +00:00
										 |  |  |  | def testGetStatusNumber(): | 
					
						
							|  |  |  |  |     print('testGetStatusNumber') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     prevStatusNumber = None | 
					
						
							|  |  |  |  |     for i in range(1, 20): | 
					
						
							|  |  |  |  |         statusNumber, published = getStatusNumber() | 
					
						
							| 
									
										
										
										
											2019-10-12 12:45:53 +00:00
										 |  |  |  |         if prevStatusNumber: | 
					
						
							|  |  |  |  |             assert len(statusNumber) == 18 | 
					
						
							|  |  |  |  |             assert int(statusNumber) > prevStatusNumber | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         prevStatusNumber = int(statusNumber) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 12:45:53 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 12:41:15 +00:00
										 |  |  |  | def testJsonString() -> None: | 
					
						
							|  |  |  |  |     print('testJsonString') | 
					
						
							| 
									
										
										
										
											2020-10-11 13:00:26 +00:00
										 |  |  |  |     filename = '.epicyon_tests_testJsonString.json' | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     messageStr = "Crème brûlée यह एक परीक्षण ह" | 
					
						
							|  |  |  |  |     testJson = { | 
					
						
							| 
									
										
										
										
											2019-11-09 12:13:39 +00:00
										 |  |  |  |         "content": messageStr | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert saveJson(testJson, filename) | 
					
						
							|  |  |  |  |     receivedJson = loadJson(filename, 0) | 
					
						
							| 
									
										
										
										
											2019-11-09 12:13:39 +00:00
										 |  |  |  |     assert receivedJson | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert receivedJson['content'] == messageStr | 
					
						
							|  |  |  |  |     encodedStr = json.dumps(testJson, ensure_ascii=False) | 
					
						
							| 
									
										
										
										
											2019-11-09 12:52:47 +00:00
										 |  |  |  |     assert messageStr in encodedStr | 
					
						
							| 
									
										
										
										
											2020-10-11 13:00:26 +00:00
										 |  |  |  |     os.remove(filename) | 
					
						
							| 
									
										
										
										
											2019-11-09 12:13:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  | def testSaveLoadJson(): | 
					
						
							|  |  |  |  |     print('testSaveLoadJson') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testJson = { | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  |         "param1": 3, | 
					
						
							| 
									
										
										
										
											2019-11-23 10:20:30 +00:00
										 |  |  |  |         "param2": '"Crème brûlée यह एक परीक्षण ह"' | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-11 13:03:08 +00:00
										 |  |  |  |     testFilename = '.epicyon_tests_testSaveLoadJson.json' | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  |     if os.path.isfile(testFilename): | 
					
						
							|  |  |  |  |         os.remove(testFilename) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert saveJson(testJson, testFilename) | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  |     assert os.path.isfile(testFilename) | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     testLoadJson = loadJson(testFilename) | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  |     assert(testLoadJson) | 
					
						
							|  |  |  |  |     assert testLoadJson.get('param1') | 
					
						
							|  |  |  |  |     assert testLoadJson.get('param2') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     assert testLoadJson['param1'] == 3 | 
					
						
							|  |  |  |  |     assert testLoadJson['param2'] == '"Crème brûlée यह एक परीक्षण ह"' | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  |     os.remove(testFilename) | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |  | def testTheme(): | 
					
						
							|  |  |  |  |     print('testTheme') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     css = 'somestring --background-value: 24px; --foreground-value: 24px;' | 
					
						
							|  |  |  |  |     result = setCSSparam(css, 'background-value', '32px') | 
					
						
							|  |  |  |  |     assert result == \ | 
					
						
							|  |  |  |  |         'somestring --background-value: 32px; --foreground-value: 24px;' | 
					
						
							|  |  |  |  |     css = \ | 
					
						
							|  |  |  |  |         'somestring --background-value: 24px; --foreground-value: 24px; ' + \ | 
					
						
							|  |  |  |  |         '--background-value: 24px;' | 
					
						
							|  |  |  |  |     result = setCSSparam(css, 'background-value', '32px') | 
					
						
							|  |  |  |  |     assert result == \ | 
					
						
							|  |  |  |  |         'somestring --background-value: 32px; --foreground-value: 24px; ' + \ | 
					
						
							|  |  |  |  |         '--background-value: 32px;' | 
					
						
							|  |  |  |  |     css = '--background-value: 24px; --foreground-value: 24px;' | 
					
						
							|  |  |  |  |     result = setCSSparam(css, 'background-value', '32px') | 
					
						
							|  |  |  |  |     assert result == '--background-value: 32px; --foreground-value: 24px;' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-24 11:28:58 +00:00
										 |  |  |  | def testRecentPostsCache(): | 
					
						
							|  |  |  |  |     print('testRecentPostsCache') | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |     recentPostsCache = {} | 
					
						
							|  |  |  |  |     maxRecentPosts = 3 | 
					
						
							|  |  |  |  |     htmlStr = '<html></html>' | 
					
						
							| 
									
										
										
										
											2019-11-24 11:28:58 +00:00
										 |  |  |  |     for i in range(5): | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         postJsonObject = { | 
					
						
							| 
									
										
										
										
											2019-11-24 11:28:58 +00:00
										 |  |  |  |             "id": "https://somesite.whatever/users/someuser/statuses/"+str(i) | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-04-05 13:25:47 +00:00
										 |  |  |  |         updateRecentPostsCache(recentPostsCache, maxRecentPosts, | 
					
						
							|  |  |  |  |                                postJsonObject, htmlStr) | 
					
						
							|  |  |  |  |     assert len(recentPostsCache['index']) == maxRecentPosts | 
					
						
							|  |  |  |  |     assert len(recentPostsCache['json'].items()) == maxRecentPosts | 
					
						
							|  |  |  |  |     assert len(recentPostsCache['html'].items()) == maxRecentPosts | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-24 11:28:58 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-14 13:25:38 +00:00
										 |  |  |  | def testRemoveTextFormatting(): | 
					
						
							|  |  |  |  |     print('testRemoveTextFormatting') | 
					
						
							|  |  |  |  |     testStr = '<p>Text without formatting</p>' | 
					
						
							|  |  |  |  |     resultStr = removeTextFormatting(testStr) | 
					
						
							|  |  |  |  |     assert(resultStr == testStr) | 
					
						
							|  |  |  |  |     testStr = '<p>Text <i>with</i> <h3>formatting</h3></p>' | 
					
						
							|  |  |  |  |     resultStr = removeTextFormatting(testStr) | 
					
						
							|  |  |  |  |     assert(resultStr == '<p>Text with formatting</p>') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  | def testJsonld(): | 
					
						
							|  |  |  |  |     print("testJsonld") | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  |     jldDocument = { | 
					
						
							| 
									
										
										
										
											2021-01-03 18:20:25 +00:00
										 |  |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  |         "actor": "https://somesite.net/users/gerbil", | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  |         "description": "My json document", | 
					
						
							|  |  |  |  |         "numberField": 83582, | 
					
						
							|  |  |  |  |         "object": { | 
					
						
							| 
									
										
										
										
											2021-01-03 14:34:27 +00:00
										 |  |  |  |             "content": "valid content" | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     # privateKeyPem, publicKeyPem = generateRSAKey() | 
					
						
							|  |  |  |  |     privateKeyPem = '-----BEGIN RSA PRIVATE KEY-----\n' \ | 
					
						
							|  |  |  |  |         'MIIEowIBAAKCAQEAod9iHfIn4ugY/2byFrFjUprrFLkkH5bCrjiBq2/MdHFg99IQ\n' \ | 
					
						
							|  |  |  |  |         '7li2x2mg5fkBMhU5SJIxlN8kiZMFq7JUXSA97Yo4puhVubqTSHihIh6Xn2mTjTgs\n' \ | 
					
						
							|  |  |  |  |         'zNo9SBbmN3YiyBPTcr0rF4jGWZAduJ8u6i7Eky2QH+UBKyUNRZrcfoVq+7grHUIA\n' \ | 
					
						
							|  |  |  |  |         '45pE7vAfEEWtgRiw32Nwlx55N3hayHax0y8gMdKEF/vfYKRLcM7rZgEASMtlCpgy\n' \ | 
					
						
							|  |  |  |  |         'fsyHwFCDzl/BP8AhP9u3dM+SEundeAvF58AiXx1pKvBpxqttDNAsKWCRQ06/WI/W\n' \ | 
					
						
							|  |  |  |  |         '2Rwihl9yCjobqRoFsZ/cTEi6FG9AbDAds5YjTwIDAQABAoIBAERL3rbpy8Bl0t43\n' \ | 
					
						
							|  |  |  |  |         'jh7a+yAIMvVMZBxb3InrV3KAug/LInGNFQ2rKnsaawN8uu9pmwCuhfLc7yqIeJUH\n' \ | 
					
						
							|  |  |  |  |         'qaadCuPlNJ/fWQQC309tbfbaV3iv78xejjBkSATZfIqb8nLeQpGflMXaNG3na1LQ\n' \ | 
					
						
							|  |  |  |  |         '/tdZoiDC0ZNTaNnOSTo765oKKqhHUTQkwkGChrwG3Js5jekV4zpPMLhUafXk6ksd\n' \ | 
					
						
							|  |  |  |  |         '8XLlZdCF3RUnuguXAg2xP/duxMYmTCx3eeGPkXBPQl0pahu8/6OtBoYvBrqNdQcx\n' \ | 
					
						
							|  |  |  |  |         'jnEtYX9PCqDY3hAXW9GWsxNfu02DKhWigFHFNRUQtMI++438+QIfzXPslE2bTQIt\n' \ | 
					
						
							|  |  |  |  |         '0OXUlwECgYEAxTKUZ7lwIBb5XKPJq53RQmX66M3ArxI1RzFSKm1+/CmxvYiN0c+5\n' \ | 
					
						
							|  |  |  |  |         '2Aq62WEIauX6hoZ7yQb4zhdeNRzinLR7rsmBvIcP12FidXG37q9v3Vu70KmHniJE\n' \ | 
					
						
							|  |  |  |  |         'TPbt5lHQ0bNACFxkar4Ab/JZN4CkMRgJdlcZ5boYNmcGOYCvw9izuM8CgYEA0iQ1\n' \ | 
					
						
							|  |  |  |  |         'khIFZ6fCiXwVRGvEHmqSnkBmBHz8MY8fczv2Z4Gzfq3Tlh9VxpigK2F2pFt7keWc\n' \ | 
					
						
							|  |  |  |  |         '53HerYFHFpf5otDhEyRwA1LyIcwbj5HopumxsB2WG+/M2as45lLfWa6KO73OtPpU\n' \ | 
					
						
							|  |  |  |  |         'wGZYW+i/otdk9eFphceYtw19mxI+3lYoeI8EjYECgYBxOtTKJkmCs45lqkp/d3QT\n' \ | 
					
						
							|  |  |  |  |         '2zjSempcXGkpQuG6KPtUUaCUgxdj1RISQj792OCbeQh8PDZRvOYaeIKInthkQKIQ\n' \ | 
					
						
							|  |  |  |  |         'P/Z1yVvIQUvmwfBqZmQmR6k1bFLJ80UiqFr7+BiegH2RD3Q9cnIP1aly3DPrWLD+\n' \ | 
					
						
							|  |  |  |  |         'OY9OQKfsfQWu+PxzyTeRMwKBgD8Zjlh5PtQ8RKcB8mTkMzSq7bHFRpzsZtH+1wPE\n' \ | 
					
						
							|  |  |  |  |         'Kp40DRDp41H9wMTsiZPdJUH/EmDh4LaCs8nHuu/m3JfuPtd/pn7pBjntzwzSVFji\n' \ | 
					
						
							|  |  |  |  |         'bW+jwrJK1Gk8B87pbZXBWlLMEOi5Dn/je37Fqd2c7f0DHauFHq9AxsmsteIPXwGs\n' \ | 
					
						
							|  |  |  |  |         'eEKBAoGBAIzJX/5yFp3ObkPracIfOJ/U/HF1UdP6Y8qmOJBZOg5s9Y+JAdY76raK\n' \ | 
					
						
							|  |  |  |  |         '0SbZPsOpuFUdTiRkSI3w/p1IuM5dPxgCGH9MHqjqogU5QwXr3vLF+a/PFhINkn1x\n' \ | 
					
						
							|  |  |  |  |         'lozRZjDcF1y6xHfExotPC973UZnKEviq9/FqOsovZpvSQkzAYSZF\n' \ | 
					
						
							|  |  |  |  |         '-----END RSA PRIVATE KEY-----' | 
					
						
							|  |  |  |  |     publicKeyPem = '-----BEGIN PUBLIC KEY-----\n' \ | 
					
						
							|  |  |  |  |         'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAod9iHfIn4ugY/2byFrFj\n' \ | 
					
						
							|  |  |  |  |         'UprrFLkkH5bCrjiBq2/MdHFg99IQ7li2x2mg5fkBMhU5SJIxlN8kiZMFq7JUXSA9\n' \ | 
					
						
							|  |  |  |  |         '7Yo4puhVubqTSHihIh6Xn2mTjTgszNo9SBbmN3YiyBPTcr0rF4jGWZAduJ8u6i7E\n' \ | 
					
						
							|  |  |  |  |         'ky2QH+UBKyUNRZrcfoVq+7grHUIA45pE7vAfEEWtgRiw32Nwlx55N3hayHax0y8g\n' \ | 
					
						
							|  |  |  |  |         'MdKEF/vfYKRLcM7rZgEASMtlCpgyfsyHwFCDzl/BP8AhP9u3dM+SEundeAvF58Ai\n' \ | 
					
						
							|  |  |  |  |         'Xx1pKvBpxqttDNAsKWCRQ06/WI/W2Rwihl9yCjobqRoFsZ/cTEi6FG9AbDAds5Yj\n' \ | 
					
						
							|  |  |  |  |         'TwIDAQAB\n' \ | 
					
						
							|  |  |  |  |         '-----END PUBLIC KEY-----' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  |     signedDocument = jldDocument.copy() | 
					
						
							|  |  |  |  |     generateJsonSignature(signedDocument, privateKeyPem) | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  |     assert(signedDocument) | 
					
						
							| 
									
										
										
										
											2020-06-15 13:35:33 +00:00
										 |  |  |  |     assert(signedDocument.get('signature')) | 
					
						
							|  |  |  |  |     assert(signedDocument['signature'].get('signatureValue')) | 
					
						
							|  |  |  |  |     assert(signedDocument['signature'].get('type')) | 
					
						
							|  |  |  |  |     assert(len(signedDocument['signature']['signatureValue']) > 50) | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  |     # print(str(signedDocument['signature'])) | 
					
						
							|  |  |  |  |     assert(signedDocument['signature']['type'] == 'RsaSignature2017') | 
					
						
							|  |  |  |  |     assert(verifyJsonSignature(signedDocument, publicKeyPem)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-03 14:31:35 +00:00
										 |  |  |  |     # alter the signed document | 
					
						
							| 
									
										
										
										
											2021-01-03 18:20:25 +00:00
										 |  |  |  |     signedDocument['object']['content'] = 'forged content' | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  |     assert(not verifyJsonSignature(signedDocument, publicKeyPem)) | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-03 15:27:59 +00:00
										 |  |  |  |     jldDocument2 = { | 
					
						
							| 
									
										
										
										
											2021-01-03 18:20:25 +00:00
										 |  |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  |         "actor": "https://somesite.net/users/gerbil", | 
					
						
							| 
									
										
										
										
											2021-01-03 15:27:59 +00:00
										 |  |  |  |         "description": "Another json document", | 
					
						
							|  |  |  |  |         "numberField": 13353, | 
					
						
							|  |  |  |  |         "object": { | 
					
						
							|  |  |  |  |             "content": "More content" | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  |     signedDocument2 = jldDocument2.copy() | 
					
						
							|  |  |  |  |     generateJsonSignature(signedDocument2, privateKeyPem) | 
					
						
							| 
									
										
										
										
											2021-01-03 15:27:59 +00:00
										 |  |  |  |     assert(signedDocument2) | 
					
						
							|  |  |  |  |     assert(signedDocument2.get('signature')) | 
					
						
							|  |  |  |  |     assert(signedDocument2['signature'].get('signatureValue')) | 
					
						
							|  |  |  |  |     # changed signature on different document | 
					
						
							|  |  |  |  |     if signedDocument['signature']['signatureValue'] == \ | 
					
						
							|  |  |  |  |        signedDocument2['signature']['signatureValue']: | 
					
						
							|  |  |  |  |         print('json signature has not changed for different documents') | 
					
						
							| 
									
										
										
										
											2021-01-04 19:02:24 +00:00
										 |  |  |  |     assert '.' not in str(signedDocument['signature']['signatureValue']) | 
					
						
							|  |  |  |  |     assert len(str(signedDocument['signature']['signatureValue'])) > 340 | 
					
						
							| 
									
										
										
										
											2021-01-03 18:20:25 +00:00
										 |  |  |  |     assert(signedDocument['signature']['signatureValue'] != | 
					
						
							|  |  |  |  |            signedDocument2['signature']['signatureValue']) | 
					
						
							| 
									
										
										
										
											2021-01-03 15:27:59 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:55:19 +00:00
										 |  |  |  | def testSiteIsActive(): | 
					
						
							|  |  |  |  |     print('testSiteIsActive') | 
					
						
							| 
									
										
										
										
											2021-02-10 11:24:34 +00:00
										 |  |  |  |     assert(siteIsActive('https://archive.org')) | 
					
						
							| 
									
										
										
										
											2020-06-22 16:55:19 +00:00
										 |  |  |  |     assert(siteIsActive('https://mastodon.social')) | 
					
						
							|  |  |  |  |     assert(not siteIsActive('https://notarealwebsite.a.b.c')) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 14:18:02 +00:00
										 |  |  |  | def testRemoveHtml(): | 
					
						
							|  |  |  |  |     print('testRemoveHtml') | 
					
						
							|  |  |  |  |     testStr = 'This string has no html.' | 
					
						
							|  |  |  |  |     assert(removeHtml(testStr) == testStr) | 
					
						
							|  |  |  |  |     testStr = 'This string <a href="1234.567">has html</a>.' | 
					
						
							|  |  |  |  |     assert(removeHtml(testStr) == 'This string has html.') | 
					
						
							| 
									
										
										
										
											2021-03-23 10:52:10 +00:00
										 |  |  |  |     testStr = '<label>This string has.</label><label>Two labels.</label>' | 
					
						
							|  |  |  |  |     assert(removeHtml(testStr) == 'This string has. Two labels.') | 
					
						
							| 
									
										
										
										
											2021-03-23 10:38:03 +00:00
										 |  |  |  |     testStr = '<p>This string has.</p><p>Two paragraphs.</p>' | 
					
						
							| 
									
										
										
										
											2021-03-23 10:52:10 +00:00
										 |  |  |  |     assert(removeHtml(testStr) == 'This string has.\n\nTwo paragraphs.') | 
					
						
							|  |  |  |  |     testStr = 'This string has.<br>A new line.' | 
					
						
							|  |  |  |  |     assert(removeHtml(testStr) == 'This string has.\nA new line.') | 
					
						
							|  |  |  |  |     testStr = '<p>This string contains a url http://somesite.or.other</p>' | 
					
						
							| 
									
										
										
										
											2021-03-23 11:22:09 +00:00
										 |  |  |  |     assert(removeHtml(testStr) == | 
					
						
							| 
									
										
										
										
											2021-03-23 10:52:10 +00:00
										 |  |  |  |            'This string contains a url http://somesite.or.other') | 
					
						
							| 
									
										
										
										
											2020-07-07 14:18:02 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-13 14:48:45 +00:00
										 |  |  |  | def testDangerousCSS(): | 
					
						
							|  |  |  |  |     print('testDangerousCSS') | 
					
						
							|  |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     for subdir, dirs, files in os.walk(baseDir): | 
					
						
							|  |  |  |  |         for f in files: | 
					
						
							|  |  |  |  |             if not f.endswith('.css'): | 
					
						
							|  |  |  |  |                 continue | 
					
						
							|  |  |  |  |             assert not dangerousCSS(baseDir + '/' + f, False) | 
					
						
							|  |  |  |  |         break | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  | def testDangerousMarkup(): | 
					
						
							|  |  |  |  |     print('testDangerousMarkup') | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     allowLocalNetworkAccess = False | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This is a valid message</p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(not dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = 'This is a valid message without markup' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(not dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This is a valid-looking message. But wait... ' + \ | 
					
						
							|  |  |  |  |         '<script>document.getElementById("concentrated")' + \ | 
					
						
							|  |  |  |  |         '.innerHTML = "evil";</script></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-19 11:29:37 +00:00
										 |  |  |  |     content = '<p>This is a valid-looking message. But wait... ' + \ | 
					
						
							|  |  |  |  |         '<script>document.getElementById("concentrated")' + \ | 
					
						
							|  |  |  |  |         '.innerHTML = "evil";</script></p>' | 
					
						
							|  |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 10:36:24 +00:00
										 |  |  |  |     content = '<p>This html contains more than you expected... ' + \ | 
					
						
							|  |  |  |  |         '<script language="javascript">document.getElementById("abc")' + \ | 
					
						
							|  |  |  |  |         '.innerHTML = "def";</script></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-15 10:36:24 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This is a valid-looking message. But wait... ' + \ | 
					
						
							|  |  |  |  |         '<script src="https://evilsite/payload.js" /></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This message embeds an evil frame.' + \ | 
					
						
							|  |  |  |  |         '<iframe src="somesite"></iframe></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This message tries to obfuscate an evil frame.' + \ | 
					
						
							|  |  |  |  |         '<  iframe     src = "somesite"></    iframe  ></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This message is not necessarily evil, but annoying.' + \ | 
					
						
							|  |  |  |  |         '<hr><br><br><br><br><br><br><br><hr><hr></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This message contans a ' + \ | 
					
						
							|  |  |  |  |         '<a href="https://validsite/index.html">valid link.</a></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(not dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     content = '<p>This message contans a ' + \ | 
					
						
							|  |  |  |  |         '<a href="https://validsite/iframe.html">' + \ | 
					
						
							|  |  |  |  |         'valid link having invalid but harmless name.</a></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(not dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  |     content = '<p>This message which <a href="127.0.0.1:8736">' + \ | 
					
						
							|  |  |  |  |         'tries to access the local network</a></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     content = '<p>This message which <a href="http://192.168.5.10:7235">' + \ | 
					
						
							|  |  |  |  |         'tries to access the local network</a></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     content = '<p>127.0.0.1 This message which does not access ' + \ | 
					
						
							|  |  |  |  |         'the local network</a></p>' | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |  |     assert(not dangerousMarkup(content, allowLocalNetworkAccess)) | 
					
						
							| 
									
										
										
										
											2020-11-11 09:42:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-02 17:01:12 +00:00
										 |  |  |  | def runHtmlReplaceQuoteMarks(): | 
					
						
							|  |  |  |  |     print('htmlReplaceQuoteMarks') | 
					
						
							|  |  |  |  |     testStr = 'The "cat" "sat" on the mat' | 
					
						
							|  |  |  |  |     result = htmlReplaceQuoteMarks(testStr) | 
					
						
							| 
									
										
										
										
											2020-08-02 18:09:50 +00:00
										 |  |  |  |     assert result == 'The “cat” “sat” on the mat' | 
					
						
							| 
									
										
										
										
											2020-08-02 17:01:12 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     testStr = 'The cat sat on the mat' | 
					
						
							|  |  |  |  |     result = htmlReplaceQuoteMarks(testStr) | 
					
						
							|  |  |  |  |     assert result == 'The cat sat on the mat' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     testStr = '"hello"' | 
					
						
							|  |  |  |  |     result = htmlReplaceQuoteMarks(testStr) | 
					
						
							| 
									
										
										
										
											2020-08-02 18:09:50 +00:00
										 |  |  |  |     assert result == '“hello”' | 
					
						
							| 
									
										
										
										
											2020-08-02 17:01:12 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-02 19:16:22 +00:00
										 |  |  |  |     testStr = '"hello" <a href="somesite.html">"test" html</a>' | 
					
						
							| 
									
										
										
										
											2020-08-02 17:17:51 +00:00
										 |  |  |  |     result = htmlReplaceQuoteMarks(testStr) | 
					
						
							| 
									
										
										
										
											2020-08-02 19:16:22 +00:00
										 |  |  |  |     assert result == '“hello” <a href="somesite.html">“test” html</a>' | 
					
						
							| 
									
										
										
										
											2020-08-02 17:17:51 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-02 17:01:12 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 18:32:16 +00:00
										 |  |  |  | def testJsonPostAllowsComments(): | 
					
						
							|  |  |  |  |     print('testJsonPostAllowsComments') | 
					
						
							|  |  |  |  |     postJsonObject = { | 
					
						
							|  |  |  |  |         "id": "123" | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     assert jsonPostAllowsComments(postJsonObject) | 
					
						
							|  |  |  |  |     postJsonObject = { | 
					
						
							|  |  |  |  |         "id": "123", | 
					
						
							|  |  |  |  |         "commentsEnabled": False | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     assert not jsonPostAllowsComments(postJsonObject) | 
					
						
							|  |  |  |  |     postJsonObject = { | 
					
						
							|  |  |  |  |         "id": "123", | 
					
						
							|  |  |  |  |         "commentsEnabled": True | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     assert jsonPostAllowsComments(postJsonObject) | 
					
						
							|  |  |  |  |     postJsonObject = { | 
					
						
							|  |  |  |  |         "id": "123", | 
					
						
							|  |  |  |  |         "object": { | 
					
						
							|  |  |  |  |             "commentsEnabled": True | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     assert jsonPostAllowsComments(postJsonObject) | 
					
						
							|  |  |  |  |     postJsonObject = { | 
					
						
							|  |  |  |  |         "id": "123", | 
					
						
							|  |  |  |  |         "object": { | 
					
						
							|  |  |  |  |             "commentsEnabled": False | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     assert not jsonPostAllowsComments(postJsonObject) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 11:13:35 +00:00
										 |  |  |  | def testRemoveIdEnding(): | 
					
						
							|  |  |  |  |     print('testRemoveIdEnding') | 
					
						
							|  |  |  |  |     testStr = 'https://activitypub.somedomain.net' | 
					
						
							|  |  |  |  |     resultStr = removeIdEnding(testStr) | 
					
						
							|  |  |  |  |     assert resultStr == 'https://activitypub.somedomain.net' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     testStr = \ | 
					
						
							|  |  |  |  |         'https://activitypub.somedomain.net/users/foo/' + \ | 
					
						
							|  |  |  |  |         'statuses/34544814814/activity' | 
					
						
							|  |  |  |  |     resultStr = removeIdEnding(testStr) | 
					
						
							|  |  |  |  |     assert resultStr == \ | 
					
						
							|  |  |  |  |         'https://activitypub.somedomain.net/users/foo/statuses/34544814814' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     testStr = \ | 
					
						
							|  |  |  |  |         'https://undo.somedomain.net/users/foo/statuses/34544814814/undo' | 
					
						
							|  |  |  |  |     resultStr = removeIdEnding(testStr) | 
					
						
							|  |  |  |  |     assert resultStr == \ | 
					
						
							|  |  |  |  |         'https://undo.somedomain.net/users/foo/statuses/34544814814' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     testStr = \ | 
					
						
							|  |  |  |  |         'https://event.somedomain.net/users/foo/statuses/34544814814/event' | 
					
						
							|  |  |  |  |     resultStr = removeIdEnding(testStr) | 
					
						
							|  |  |  |  |     assert resultStr == \ | 
					
						
							|  |  |  |  |         'https://event.somedomain.net/users/foo/statuses/34544814814' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-25 19:35:55 +00:00
										 |  |  |  | def testValidContentWarning(): | 
					
						
							|  |  |  |  |     print('testValidContentWarning') | 
					
						
							|  |  |  |  |     resultStr = validContentWarning('Valid content warning') | 
					
						
							|  |  |  |  |     assert resultStr == 'Valid content warning' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     resultStr = validContentWarning('Invalid #content warning') | 
					
						
							|  |  |  |  |     assert resultStr == 'Invalid content warning' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     resultStr = \ | 
					
						
							|  |  |  |  |         validContentWarning('Invalid <a href="somesite">content warning</a>') | 
					
						
							|  |  |  |  |     assert resultStr == 'Invalid content warning' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 18:21:57 +00:00
										 |  |  |  | def testTranslations(): | 
					
						
							|  |  |  |  |     print('testTranslations') | 
					
						
							|  |  |  |  |     languagesStr = ('ar', 'ca', 'cy', 'de', 'es', 'fr', 'ga', | 
					
						
							|  |  |  |  |                     'hi', 'it', 'ja', 'oc', 'pt', 'ru', 'zh') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # load all translations into a dict | 
					
						
							|  |  |  |  |     langDict = {} | 
					
						
							|  |  |  |  |     for lang in languagesStr: | 
					
						
							|  |  |  |  |         langJson = loadJson('translations/' + lang + '.json') | 
					
						
							| 
									
										
										
										
											2020-08-29 11:14:19 +00:00
										 |  |  |  |         if not langJson: | 
					
						
							|  |  |  |  |             print('Missing language file ' + | 
					
						
							|  |  |  |  |                   'translations/' + lang + '.json') | 
					
						
							| 
									
										
										
										
											2020-08-26 18:21:57 +00:00
										 |  |  |  |         assert langJson | 
					
						
							|  |  |  |  |         langDict[lang] = langJson | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # load english translations | 
					
						
							|  |  |  |  |     translationsJson = loadJson('translations/en.json') | 
					
						
							|  |  |  |  |     # test each english string exists in the other language files | 
					
						
							|  |  |  |  |     for englishStr, translatedStr in translationsJson.items(): | 
					
						
							|  |  |  |  |         for lang in languagesStr: | 
					
						
							|  |  |  |  |             langJson = langDict[lang] | 
					
						
							|  |  |  |  |             if not langJson.get(englishStr): | 
					
						
							|  |  |  |  |                 print(englishStr + ' is missing from ' + lang + '.json') | 
					
						
							|  |  |  |  |             assert langJson.get(englishStr) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 18:13:29 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 18:48:32 +00:00
										 |  |  |  | def testConstantTimeStringCheck(): | 
					
						
							|  |  |  |  |     print('testConstantTimeStringCheck') | 
					
						
							|  |  |  |  |     assert constantTimeStringCheck('testing', 'testing') | 
					
						
							|  |  |  |  |     assert not constantTimeStringCheck('testing', '1234') | 
					
						
							|  |  |  |  |     assert not constantTimeStringCheck('testing', '1234567') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     itterations = 256 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     start = time.time() | 
					
						
							|  |  |  |  |     for timingTest in range(itterations): | 
					
						
							|  |  |  |  |         constantTimeStringCheck('nnjfbefefbsnjsdnvbcueftqfeuqfbqefnjeniwufgy', | 
					
						
							|  |  |  |  |                                 'nnjfbefefbsnjsdnvbcueftqfeuqfbqefnjeniwufgy') | 
					
						
							|  |  |  |  |     end = time.time() | 
					
						
							|  |  |  |  |     avTime1 = ((end - start) * 1000000 / itterations) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 18:52:18 +00:00
										 |  |  |  |     # change a single character and observe timing difference | 
					
						
							| 
									
										
										
										
											2020-09-03 18:48:32 +00:00
										 |  |  |  |     start = time.time() | 
					
						
							|  |  |  |  |     for timingTest in range(itterations): | 
					
						
							|  |  |  |  |         constantTimeStringCheck('nnjfbefefbsnjsdnvbcueftqfeuqfbqefnjeniwufgy', | 
					
						
							|  |  |  |  |                                 'nnjfbefefbsnjsdnvbcueftqfeuqfbqeznjeniwufgy') | 
					
						
							|  |  |  |  |     end = time.time() | 
					
						
							|  |  |  |  |     avTime2 = ((end - start) * 1000000 / itterations) | 
					
						
							|  |  |  |  |     timeDiffMicroseconds = abs(avTime2 - avTime1) | 
					
						
							|  |  |  |  |     # time difference should be less than 10uS | 
					
						
							| 
									
										
										
										
											2020-10-25 10:10:56 +00:00
										 |  |  |  |     assert int(timeDiffMicroseconds) < 10 | 
					
						
							| 
									
										
										
										
											2020-09-03 18:48:32 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 18:52:18 +00:00
										 |  |  |  |     # change multiple characters and observe timing difference | 
					
						
							|  |  |  |  |     start = time.time() | 
					
						
							|  |  |  |  |     for timingTest in range(itterations): | 
					
						
							|  |  |  |  |         constantTimeStringCheck('nnjfbefefbsnjsdnvbcueftqfeuqfbqefnjeniwufgy', | 
					
						
							|  |  |  |  |                                 'ano1befffbsn7sd3vbluef6qseuqfpqeznjgni9bfgi') | 
					
						
							|  |  |  |  |     end = time.time() | 
					
						
							|  |  |  |  |     avTime2 = ((end - start) * 1000000 / itterations) | 
					
						
							|  |  |  |  |     timeDiffMicroseconds = abs(avTime2 - avTime1) | 
					
						
							|  |  |  |  |     # time difference should be less than 10uS | 
					
						
							| 
									
										
										
										
											2020-10-25 10:10:56 +00:00
										 |  |  |  |     assert int(timeDiffMicroseconds) < 10 | 
					
						
							| 
									
										
										
										
											2020-09-03 18:52:18 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 18:48:32 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  | def testReplaceEmailQuote(): | 
					
						
							|  |  |  |  |     print('testReplaceEmailQuote') | 
					
						
							| 
									
										
										
										
											2020-09-14 09:41:44 +00:00
										 |  |  |  |     testStr = '<p>This content has no quote.</p>' | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  |     assert htmlReplaceEmailQuote(testStr) == testStr | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 09:41:44 +00:00
										 |  |  |  |     testStr = '<p>This content has no quote.</p>' + \ | 
					
						
							|  |  |  |  |         '<p>With multiple</p><p>lines</p>' | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  |     assert htmlReplaceEmailQuote(testStr) == testStr | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 11:30:56 +00:00
										 |  |  |  |     testStr = '<p>"This is a quoted paragraph."</p>' | 
					
						
							|  |  |  |  |     assert htmlReplaceEmailQuote(testStr) == \ | 
					
						
							|  |  |  |  |         '<p><blockquote>This is a quoted paragraph.</blockquote></p>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  |     testStr = "<p><span class=\"h-card\">" + \ | 
					
						
							|  |  |  |  |         "<a href=\"https://somewebsite/@nickname\" " + \ | 
					
						
							|  |  |  |  |         "class=\"u-url mention\">@<span>nickname</span></a></span> " + \ | 
					
						
							|  |  |  |  |         "<br />> This is a quote</p><p>Some other text.</p>" | 
					
						
							|  |  |  |  |     expectedStr = "<p><span class=\"h-card\">" + \ | 
					
						
							|  |  |  |  |         "<a href=\"https://somewebsite/@nickname\" " + \ | 
					
						
							|  |  |  |  |         "class=\"u-url mention\">@<span>nickname</span></a></span> " + \ | 
					
						
							|  |  |  |  |         "<br /><blockquote>This is a quote</blockquote></p>" + \ | 
					
						
							|  |  |  |  |         "<p>Some other text.</p>" | 
					
						
							|  |  |  |  |     resultStr = htmlReplaceEmailQuote(testStr) | 
					
						
							|  |  |  |  |     if resultStr != expectedStr: | 
					
						
							| 
									
										
										
										
											2020-09-30 22:52:39 +00:00
										 |  |  |  |         print('Result: ' + str(resultStr)) | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  |         print('Expect: ' + expectedStr) | 
					
						
							|  |  |  |  |     assert resultStr == expectedStr | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 10:25:12 +00:00
										 |  |  |  |     testStr = "<p>Some text:</p><p>> first line->second line</p>" + \ | 
					
						
							|  |  |  |  |         "<p>Some question?</p>" | 
					
						
							|  |  |  |  |     expectedStr = "<p>Some text:</p><p><blockquote>first line-<br>" + \ | 
					
						
							|  |  |  |  |         "second line</blockquote></p><p>Some question?</p>" | 
					
						
							|  |  |  |  |     resultStr = htmlReplaceEmailQuote(testStr) | 
					
						
							|  |  |  |  |     if resultStr != expectedStr: | 
					
						
							| 
									
										
										
										
											2020-09-30 22:52:39 +00:00
										 |  |  |  |         print('Result: ' + str(resultStr)) | 
					
						
							| 
									
										
										
										
											2020-09-14 10:25:12 +00:00
										 |  |  |  |         print('Expect: ' + expectedStr) | 
					
						
							|  |  |  |  |     assert resultStr == expectedStr | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-30 22:22:42 +00:00
										 |  |  |  |     testStr = "<p><span class=\"h-card\">" + \ | 
					
						
							|  |  |  |  |         "<a href=\"https://somedomain/@somenick\" " + \ | 
					
						
							|  |  |  |  |         "class=\"u-url mention\">@<span>somenick</span>" + \ | 
					
						
							|  |  |  |  |         "</a></span> </p><p>> Text1.<br />> <br />" + \ | 
					
						
							|  |  |  |  |         "> Text2<br />> <br />> Text3<br />" + \ | 
					
						
							|  |  |  |  |         "><br />> Text4<br />> <br />> " + \ | 
					
						
							|  |  |  |  |         "Text5<br />> <br />> Text6</p><p>Text7</p>" | 
					
						
							| 
									
										
										
										
											2020-09-30 22:55:53 +00:00
										 |  |  |  |     expectedStr = "<p><span class=\"h-card\">" + \ | 
					
						
							|  |  |  |  |         "<a href=\"https://somedomain/@somenick\" " + \ | 
					
						
							|  |  |  |  |         "class=\"u-url mention\">@<span>somenick</span></a>" + \ | 
					
						
							|  |  |  |  |         "</span> </p><p><blockquote> Text1.<br /><br />" + \ | 
					
						
							|  |  |  |  |         "Text2<br /><br />Text3<br />><br />Text4<br />" + \ | 
					
						
							|  |  |  |  |         "<br />Text5<br /><br />Text6</blockquote></p><p>Text7</p>" | 
					
						
							| 
									
										
										
										
											2020-09-30 22:22:42 +00:00
										 |  |  |  |     resultStr = htmlReplaceEmailQuote(testStr) | 
					
						
							|  |  |  |  |     if resultStr != expectedStr: | 
					
						
							| 
									
										
										
										
											2020-09-30 22:52:39 +00:00
										 |  |  |  |         print('Result: ' + str(resultStr)) | 
					
						
							| 
									
										
										
										
											2020-09-30 22:22:42 +00:00
										 |  |  |  |         print('Expect: ' + expectedStr) | 
					
						
							|  |  |  |  |     assert resultStr == expectedStr | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 09:33:31 +00:00
										 |  |  |  | def testRemoveHtmlTag(): | 
					
						
							|  |  |  |  |     print('testRemoveHtmlTag') | 
					
						
							|  |  |  |  |     testStr = "<p><img width=\"864\" height=\"486\" " + \ | 
					
						
							|  |  |  |  |         "src=\"https://somesiteorother.com/image.jpg\"></p>" | 
					
						
							|  |  |  |  |     resultStr = removeHtmlTag(testStr, 'width') | 
					
						
							|  |  |  |  |     assert resultStr == "<p><img height=\"486\" " + \ | 
					
						
							|  |  |  |  |         "src=\"https://somesiteorother.com/image.jpg\"></p>" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | def testHashtagRuleTree(): | 
					
						
							|  |  |  |  |     print('testHashtagRuleTree') | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     operators = ('not', 'and', 'or', 'xor', 'from', 'contains') | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     url = 'testsite.com' | 
					
						
							| 
									
										
										
										
											2020-10-18 15:10:36 +00:00
										 |  |  |  |     moderated = True | 
					
						
							|  |  |  |  |     conditionsStr = \ | 
					
						
							|  |  |  |  |         'contains "Cat" or contains "Corvid" or ' + \ | 
					
						
							|  |  |  |  |         'contains "Dormouse" or contains "Buzzard"' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							|  |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							|  |  |  |  |     assert str(tree) == str(['or', ['contains', ['"Cat"']], | 
					
						
							|  |  |  |  |                              ['contains', ['"Corvid"']], | 
					
						
							|  |  |  |  |                              ['contains', ['"Dormouse"']], | 
					
						
							|  |  |  |  |                              ['contains', ['"Buzzard"']]]) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 18:49:43 +00:00
										 |  |  |  |     content = 'This is a test' | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     moderated = True | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     conditionsStr = '#foo or #bar' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     assert str(tree) == str(['or', ['#foo'], ['#bar']]) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#foo', '#bar']) | 
					
						
							|  |  |  |  |     hashtags = ['#foo'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     hashtags = ['#carrot', '#stick'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     content = 'This is a test' | 
					
						
							|  |  |  |  |     url = 'https://testsite.com/something' | 
					
						
							|  |  |  |  |     moderated = True | 
					
						
							|  |  |  |  |     conditionsStr = '#foo and from "testsite.com"' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							|  |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							|  |  |  |  |     assert str(tree) == str(['and', ['#foo'], ['from', ['"testsite.com"']]]) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#foo']) | 
					
						
							|  |  |  |  |     hashtags = ['#foo'] | 
					
						
							| 
									
										
										
										
											2020-10-21 10:39:09 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, | 
					
						
							|  |  |  |  |                                   'othersite.net') | 
					
						
							| 
									
										
										
										
											2020-10-17 18:49:43 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     content = 'This is a test' | 
					
						
							|  |  |  |  |     moderated = True | 
					
						
							|  |  |  |  |     conditionsStr = 'contains "is a" and #foo or #bar' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							|  |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							|  |  |  |  |     assert str(tree) == \ | 
					
						
							|  |  |  |  |         str(['and', ['contains', ['"is a"']], | 
					
						
							|  |  |  |  |              ['or', ['#foo'], ['#bar']]]) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#foo', '#bar']) | 
					
						
							|  |  |  |  |     hashtags = ['#foo'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 18:49:43 +00:00
										 |  |  |  |     hashtags = ['#carrot', '#stick'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     moderated = False | 
					
						
							|  |  |  |  |     conditionsStr = 'not moderated and #foo or #bar' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							|  |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							|  |  |  |  |     assert str(tree) == \ | 
					
						
							|  |  |  |  |         str(['not', ['and', ['moderated'], ['or', ['#foo'], ['#bar']]]]) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#foo', '#bar']) | 
					
						
							|  |  |  |  |     hashtags = ['#foo'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     hashtags = ['#carrot', '#stick'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     moderated = True | 
					
						
							|  |  |  |  |     conditionsStr = 'moderated and #foo or #bar' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							|  |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							|  |  |  |  |     assert str(tree) == \ | 
					
						
							|  |  |  |  |         str(['and', ['moderated'], ['or', ['#foo'], ['#bar']]]) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#foo', '#bar']) | 
					
						
							|  |  |  |  |     hashtags = ['#foo'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     hashtags = ['#carrot', '#stick'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     conditionsStr = 'x' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     assert tree is None | 
					
						
							|  |  |  |  |     assert tagsInConditions == [] | 
					
						
							|  |  |  |  |     hashtags = ['#foo'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     conditionsStr = '#x' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     assert str(tree) == str(['#x']) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#x']) | 
					
						
							|  |  |  |  |     hashtags = ['#x'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     hashtags = ['#y', '#z'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     conditionsStr = 'not #b' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     assert str(tree) == str(['not', ['#b']]) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#b']) | 
					
						
							|  |  |  |  |     hashtags = ['#y', '#z'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     hashtags = ['#a', '#b', '#c'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     conditionsStr = '#foo or #bar and #a' | 
					
						
							|  |  |  |  |     tagsInConditions = [] | 
					
						
							| 
									
										
										
										
											2020-10-17 17:36:10 +00:00
										 |  |  |  |     tree = hashtagRuleTree(operators, conditionsStr, | 
					
						
							|  |  |  |  |                            tagsInConditions, moderated) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     assert str(tree) == str(['and', ['or', ['#foo'], ['#bar']], ['#a']]) | 
					
						
							|  |  |  |  |     assert str(tagsInConditions) == str(['#foo', '#bar', '#a']) | 
					
						
							| 
									
										
										
										
											2020-10-18 15:10:36 +00:00
										 |  |  |  |     hashtags = ['#foo', '#bar', '#a'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     hashtags = ['#bar', '#a'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     hashtags = ['#foo', '#a'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     hashtags = ['#x', '#a'] | 
					
						
							| 
									
										
										
										
											2020-10-20 17:37:15 +00:00
										 |  |  |  |     assert not hashtagRuleResolve(tree, hashtags, moderated, content, url) | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-25 10:06:54 +00:00
										 |  |  |  | def testGetNewswireTags(): | 
					
						
							|  |  |  |  |     print('testGetNewswireTags') | 
					
						
							| 
									
										
										
										
											2020-10-25 10:24:02 +00:00
										 |  |  |  |     rssDescription = '<img src="https://somesite/someimage.jpg" ' + \ | 
					
						
							| 
									
										
										
										
											2020-10-25 10:08:02 +00:00
										 |  |  |  |         'class="misc-stuff" alt="#ExcitingHashtag" ' + \ | 
					
						
							|  |  |  |  |         'srcset="https://somesite/someimage.jpg" ' + \ | 
					
						
							|  |  |  |  |         'sizes="(max-width: 864px) 100vw, 864px" />' + \ | 
					
						
							|  |  |  |  |         'Compelling description with #ExcitingHashtag, which is ' + \ | 
					
						
							|  |  |  |  |         'being posted in #BoringForum' | 
					
						
							| 
									
										
										
										
											2020-10-25 10:06:54 +00:00
										 |  |  |  |     tags = getNewswireTags(rssDescription, 10) | 
					
						
							|  |  |  |  |     assert len(tags) == 2 | 
					
						
							|  |  |  |  |     assert '#BoringForum' in tags | 
					
						
							|  |  |  |  |     assert '#ExcitingHashtag' in tags | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-08 11:24:43 +00:00
										 |  |  |  | def testFirstParagraphFromString(): | 
					
						
							|  |  |  |  |     print('testFirstParagraphFromString') | 
					
						
							|  |  |  |  |     testStr = \ | 
					
						
							|  |  |  |  |         '<p><a href="https://somesite.com/somepath">This is a test</a></p>' + \ | 
					
						
							|  |  |  |  |         '<p>This is another paragraph</p>' | 
					
						
							|  |  |  |  |     resultStr = firstParagraphFromString(testStr) | 
					
						
							| 
									
										
										
										
											2021-03-22 14:36:27 +00:00
										 |  |  |  |     if resultStr != 'This is a test': | 
					
						
							|  |  |  |  |         print(resultStr) | 
					
						
							| 
									
										
										
										
											2020-11-08 11:24:43 +00:00
										 |  |  |  |     assert resultStr == 'This is a test' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     testStr = 'Testing without html' | 
					
						
							|  |  |  |  |     resultStr = firstParagraphFromString(testStr) | 
					
						
							|  |  |  |  |     assert resultStr == testStr | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 18:43:01 +00:00
										 |  |  |  | def testParseFeedDate(): | 
					
						
							|  |  |  |  |     print('testParseFeedDate') | 
					
						
							| 
									
										
										
										
											2020-12-09 10:38:09 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-14 15:17:30 +00:00
										 |  |  |  |     pubDate = "2020-12-14T00:08:06+00:00" | 
					
						
							|  |  |  |  |     publishedDate = parseFeedDate(pubDate) | 
					
						
							|  |  |  |  |     assert publishedDate == "2020-12-14 00:08:06+00:00" | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-09 10:38:09 +00:00
										 |  |  |  |     pubDate = "Tue, 08 Dec 2020 06:24:38 -0600" | 
					
						
							|  |  |  |  |     publishedDate = parseFeedDate(pubDate) | 
					
						
							|  |  |  |  |     assert publishedDate == "2020-12-08 12:24:38+00:00" | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 18:43:01 +00:00
										 |  |  |  |     pubDate = "2020-08-27T16:12:34+00:00" | 
					
						
							|  |  |  |  |     publishedDate = parseFeedDate(pubDate) | 
					
						
							| 
									
										
										
										
											2020-11-22 19:13:41 +00:00
										 |  |  |  |     assert publishedDate == "2020-08-27 16:12:34+00:00" | 
					
						
							| 
									
										
										
										
											2020-11-22 19:01:18 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     pubDate = "Sun, 22 Nov 2020 19:51:33 +0100" | 
					
						
							|  |  |  |  |     publishedDate = parseFeedDate(pubDate) | 
					
						
							| 
									
										
										
										
											2020-11-22 20:18:10 +00:00
										 |  |  |  |     assert publishedDate == "2020-11-22 18:51:33+00:00" | 
					
						
							| 
									
										
										
										
											2020-11-22 18:43:01 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 10:53:10 +00:00
										 |  |  |  | def testValidNickname(): | 
					
						
							|  |  |  |  |     print('testValidNickname') | 
					
						
							|  |  |  |  |     domain = 'somedomain.net' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     nickname = 'myvalidnick' | 
					
						
							|  |  |  |  |     assert validNickname(domain, nickname) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     nickname = 'my.invalid.nick' | 
					
						
							|  |  |  |  |     assert not validNickname(domain, nickname) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     nickname = 'myinvalidnick?' | 
					
						
							|  |  |  |  |     assert not validNickname(domain, nickname) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     nickname = 'my invalid nick?' | 
					
						
							|  |  |  |  |     assert not validNickname(domain, nickname) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 11:11:32 +00:00
										 |  |  |  | def testGuessHashtagCategory() -> None: | 
					
						
							|  |  |  |  |     print('testGuessHashtagCategory') | 
					
						
							|  |  |  |  |     hashtagCategories = { | 
					
						
							|  |  |  |  |         "foo": ["swan", "goose"], | 
					
						
							|  |  |  |  |         "bar": ["cat", "mouse"] | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     guess = guessHashtagCategory("unspecifiedgoose", hashtagCategories) | 
					
						
							|  |  |  |  |     assert guess == "foo" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     guess = guessHashtagCategory("catpic", hashtagCategories) | 
					
						
							|  |  |  |  |     assert guess == "bar" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-13 19:05:26 +00:00
										 |  |  |  | def testGetMentionedPeople() -> None: | 
					
						
							|  |  |  |  |     print('testGetMentionedPeople') | 
					
						
							|  |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     content = "@dragon@cave.site @bat@cave.site This is a test." | 
					
						
							|  |  |  |  |     actors = getMentionedPeople(baseDir, 'https', | 
					
						
							|  |  |  |  |                                 content, | 
					
						
							|  |  |  |  |                                 'mydomain', False) | 
					
						
							|  |  |  |  |     assert actors | 
					
						
							|  |  |  |  |     assert len(actors) == 2 | 
					
						
							|  |  |  |  |     assert actors[0] == "https://cave.site/users/dragon" | 
					
						
							|  |  |  |  |     assert actors[1] == "https://cave.site/users/bat" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-13 19:53:31 +00:00
										 |  |  |  | def testReplyToPublicPost() -> None: | 
					
						
							|  |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'test7492362' | 
					
						
							|  |  |  |  |     domain = 'other.site' | 
					
						
							|  |  |  |  |     port = 443 | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     postId = httpPrefix + '://rat.site/users/ninjarodent/statuses/63746173435' | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     content = "@ninjarodent@rat.site This is a test." | 
					
						
							|  |  |  |  |     followersOnly = False | 
					
						
							|  |  |  |  |     saveToFile = False | 
					
						
							|  |  |  |  |     clientToServer = False | 
					
						
							|  |  |  |  |     commentsEnabled = True | 
					
						
							|  |  |  |  |     attachImageFilename = None | 
					
						
							|  |  |  |  |     mediaType = None | 
					
						
							|  |  |  |  |     imageDescription = 'Some description' | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2020-12-13 19:53:31 +00:00
										 |  |  |  |     reply = \ | 
					
						
							|  |  |  |  |         createPublicPost(baseDir, nickname, domain, port, httpPrefix, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          content, followersOnly, saveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, commentsEnabled, | 
					
						
							|  |  |  |  |                          attachImageFilename, mediaType, | 
					
						
							|  |  |  |  |                          imageDescription, city, postId) | 
					
						
							| 
									
										
										
										
											2020-12-13 20:07:45 +00:00
										 |  |  |  |     # print(str(reply)) | 
					
						
							| 
									
										
										
										
											2020-12-13 19:53:31 +00:00
										 |  |  |  |     assert reply['object']['content'] == \ | 
					
						
							|  |  |  |  |         '<p><span class=\"h-card\">' + \ | 
					
						
							|  |  |  |  |         '<a href=\"https://rat.site/@ninjarodent\" ' + \ | 
					
						
							|  |  |  |  |         'class=\"u-url mention\">@<span>ninjarodent</span>' + \ | 
					
						
							|  |  |  |  |         '</a></span> This is a test.</p>' | 
					
						
							|  |  |  |  |     assert reply['object']['tag'][0]['type'] == 'Mention' | 
					
						
							|  |  |  |  |     assert reply['object']['tag'][0]['name'] == '@ninjarodent@rat.site' | 
					
						
							|  |  |  |  |     assert reply['object']['tag'][0]['href'] == \ | 
					
						
							|  |  |  |  |         'https://rat.site/users/ninjarodent' | 
					
						
							|  |  |  |  |     assert len(reply['object']['to']) == 1 | 
					
						
							|  |  |  |  |     assert reply['object']['to'][0].endswith('#Public') | 
					
						
							|  |  |  |  |     assert len(reply['object']['cc']) >= 1 | 
					
						
							|  |  |  |  |     assert reply['object']['cc'][0].endswith(nickname + '/followers') | 
					
						
							|  |  |  |  |     assert len(reply['object']['tag']) == 1 | 
					
						
							|  |  |  |  |     assert len(reply['object']['cc']) == 2 | 
					
						
							|  |  |  |  |     assert reply['object']['cc'][1] == \ | 
					
						
							|  |  |  |  |         httpPrefix + '://rat.site/users/ninjarodent' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  | def getFunctionCallArgs(name: str, lines: [], startLineCtr: int) -> []: | 
					
						
							|  |  |  |  |     """Returns the arguments of a function call given lines
 | 
					
						
							|  |  |  |  |     of source code and a starting line number | 
					
						
							| 
									
										
										
										
											2020-12-22 21:27:46 +00:00
										 |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |     argsStr = lines[startLineCtr].split(name + '(')[1] | 
					
						
							|  |  |  |  |     if ')' in argsStr: | 
					
						
							|  |  |  |  |         argsStr = argsStr.split(')')[0].replace(' ', '').split(',') | 
					
						
							|  |  |  |  |         return argsStr | 
					
						
							|  |  |  |  |     for lineCtr in range(startLineCtr + 1, len(lines)): | 
					
						
							|  |  |  |  |         if ')' not in lines[lineCtr]: | 
					
						
							|  |  |  |  |             argsStr += lines[lineCtr] | 
					
						
							|  |  |  |  |             continue | 
					
						
							|  |  |  |  |         else: | 
					
						
							|  |  |  |  |             argsStr += lines[lineCtr].split(')')[0] | 
					
						
							|  |  |  |  |             break | 
					
						
							|  |  |  |  |     return argsStr.replace('\n', '').replace(' ', '').split(',') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  | def getFunctionCalls(name: str, lines: [], startLineCtr: int, | 
					
						
							|  |  |  |  |                      functionProperties: {}) -> []: | 
					
						
							|  |  |  |  |     """Returns the functions called by the given one,
 | 
					
						
							|  |  |  |  |     Starting with the given source code at the given line | 
					
						
							|  |  |  |  |     """
 | 
					
						
							|  |  |  |  |     callsFunctions = [] | 
					
						
							|  |  |  |  |     functionContentStr = '' | 
					
						
							|  |  |  |  |     for lineCtr in range(startLineCtr + 1, len(lines)): | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         lineStr = lines[lineCtr].strip() | 
					
						
							|  |  |  |  |         if lineStr.startswith('def '): | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |             break | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         if lineStr.startswith('class '): | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |             break | 
					
						
							|  |  |  |  |         functionContentStr += lines[lineCtr] | 
					
						
							|  |  |  |  |     for funcName, properties in functionProperties.items(): | 
					
						
							|  |  |  |  |         if funcName + '(' in functionContentStr: | 
					
						
							|  |  |  |  |             callsFunctions.append(funcName) | 
					
						
							|  |  |  |  |     return callsFunctions | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  | def functionArgsMatch(callArgs: [], funcArgs: []): | 
					
						
							|  |  |  |  |     """Do the function artuments match the function call arguments
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							|  |  |  |  |     if len(callArgs) == len(funcArgs): | 
					
						
							|  |  |  |  |         return True | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # count non-optional arguments | 
					
						
							|  |  |  |  |     callArgsCtr = 0 | 
					
						
							|  |  |  |  |     for a in callArgs: | 
					
						
							|  |  |  |  |         if a == 'self': | 
					
						
							|  |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         if '=' not in a or a.startswith("'"): | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |             callArgsCtr += 1 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     funcArgsCtr = 0 | 
					
						
							|  |  |  |  |     for a in funcArgs: | 
					
						
							|  |  |  |  |         if a == 'self': | 
					
						
							|  |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         if '=' not in a or a.startswith("'"): | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |             funcArgsCtr += 1 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return callArgsCtr >= funcArgsCtr | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  | def testFunctions(): | 
					
						
							|  |  |  |  |     print('testFunctions') | 
					
						
							|  |  |  |  |     function = {} | 
					
						
							|  |  |  |  |     functionProperties = {} | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |     modules = {} | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     for subdir, dirs, files in os.walk('.'): | 
					
						
							|  |  |  |  |         for sourceFile in files: | 
					
						
							|  |  |  |  |             if not sourceFile.endswith('.py'): | 
					
						
							|  |  |  |  |                 continue | 
					
						
							|  |  |  |  |             modName = sourceFile.replace('.py', '') | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |             modules[modName] = { | 
					
						
							|  |  |  |  |                 'functions': [] | 
					
						
							|  |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |             sourceStr = '' | 
					
						
							|  |  |  |  |             with open(sourceFile, "r") as f: | 
					
						
							|  |  |  |  |                 sourceStr = f.read() | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |                 modules[modName]['source'] = sourceStr | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |             with open(sourceFile, "r") as f: | 
					
						
							|  |  |  |  |                 lines = f.readlines() | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |                 modules[modName]['lines'] = lines | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |                 for line in lines: | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |                     if not line.strip().startswith('def '): | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |                         continue | 
					
						
							|  |  |  |  |                     methodName = line.split('def ', 1)[1].split('(')[0] | 
					
						
							|  |  |  |  |                     methodArgs = \ | 
					
						
							|  |  |  |  |                         sourceStr.split('def ' + methodName + '(')[1] | 
					
						
							|  |  |  |  |                     methodArgs = methodArgs.split(')')[0] | 
					
						
							|  |  |  |  |                     methodArgs = methodArgs.replace(' ', '').split(',') | 
					
						
							|  |  |  |  |                     if function.get(modName): | 
					
						
							|  |  |  |  |                         function[modName].append(methodName) | 
					
						
							|  |  |  |  |                     else: | 
					
						
							|  |  |  |  |                         function[modName] = [methodName] | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |                     if methodName not in modules[modName]['functions']: | 
					
						
							|  |  |  |  |                         modules[modName]['functions'].append(methodName) | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |                     functionProperties[methodName] = { | 
					
						
							|  |  |  |  |                         "args": methodArgs, | 
					
						
							|  |  |  |  |                         "module": modName, | 
					
						
							|  |  |  |  |                         "calledInModule": [] | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |         break | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |     excludeFuncArgs = [ | 
					
						
							|  |  |  |  |         'pyjsonld' | 
					
						
							|  |  |  |  |     ] | 
					
						
							|  |  |  |  |     excludeFuncs = [ | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         'link', | 
					
						
							|  |  |  |  |         'set', | 
					
						
							|  |  |  |  |         'get' | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |     # which modules is each function used within? | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |     for modName, modProperties in modules.items(): | 
					
						
							| 
									
										
										
										
											2020-12-22 13:04:49 +00:00
										 |  |  |  |         print('Module: ' + modName + ' ✓') | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |         for name, properties in functionProperties.items(): | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |             lineCtr = 0 | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |             for line in modules[modName]['lines']: | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |                 lineStr = line.strip() | 
					
						
							|  |  |  |  |                 if lineStr.startswith('def '): | 
					
						
							|  |  |  |  |                     lineCtr += 1 | 
					
						
							|  |  |  |  |                     continue | 
					
						
							|  |  |  |  |                 if lineStr.startswith('class '): | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                     lineCtr += 1 | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |                     continue | 
					
						
							|  |  |  |  |                 if name + '(' in line: | 
					
						
							|  |  |  |  |                     modList = \ | 
					
						
							|  |  |  |  |                         functionProperties[name]['calledInModule'] | 
					
						
							|  |  |  |  |                     if modName not in modList: | 
					
						
							|  |  |  |  |                         modList.append(modName) | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |  |                     if modName in excludeFuncArgs: | 
					
						
							|  |  |  |  |                         lineCtr += 1 | 
					
						
							|  |  |  |  |                         continue | 
					
						
							|  |  |  |  |                     if name in excludeFuncs: | 
					
						
							|  |  |  |  |                         lineCtr += 1 | 
					
						
							|  |  |  |  |                         continue | 
					
						
							|  |  |  |  |                     callArgs = \ | 
					
						
							|  |  |  |  |                         getFunctionCallArgs(name, | 
					
						
							|  |  |  |  |                                             modules[modName]['lines'], | 
					
						
							|  |  |  |  |                                             lineCtr) | 
					
						
							|  |  |  |  |                     if not functionArgsMatch(callArgs, | 
					
						
							|  |  |  |  |                                              functionProperties[name]['args']): | 
					
						
							|  |  |  |  |                         print('Call to function ' + name + | 
					
						
							|  |  |  |  |                               ' does not match its arguments') | 
					
						
							|  |  |  |  |                         print('def args: ' + | 
					
						
							|  |  |  |  |                               str(len(functionProperties[name]['args'])) + | 
					
						
							|  |  |  |  |                               '\n' + str(functionProperties[name]['args'])) | 
					
						
							|  |  |  |  |                         print('Call args: ' + str(len(callArgs)) + '\n' + | 
					
						
							|  |  |  |  |                               str(callArgs)) | 
					
						
							|  |  |  |  |                         print('module ' + modName + ' line ' + str(lineCtr)) | 
					
						
							|  |  |  |  |                         assert False | 
					
						
							|  |  |  |  |                 lineCtr += 1 | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # don't check these functions, because they are procedurally called | 
					
						
							|  |  |  |  |     exclusions = [ | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         'do_GET', | 
					
						
							|  |  |  |  |         'do_POST', | 
					
						
							|  |  |  |  |         'do_HEAD', | 
					
						
							|  |  |  |  |         '__run', | 
					
						
							|  |  |  |  |         'globaltrace', | 
					
						
							|  |  |  |  |         'localtrace', | 
					
						
							|  |  |  |  |         'kill', | 
					
						
							|  |  |  |  |         'clone', | 
					
						
							|  |  |  |  |         'unregister_rdf_parser', | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |         'set_document_loader', | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         'has_property', | 
					
						
							|  |  |  |  |         'has_value', | 
					
						
							|  |  |  |  |         'add_value', | 
					
						
							|  |  |  |  |         'get_values', | 
					
						
							|  |  |  |  |         'remove_property', | 
					
						
							|  |  |  |  |         'remove_value', | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |         'normalize', | 
					
						
							|  |  |  |  |         'get_document_loader', | 
					
						
							|  |  |  |  |         'runInboxQueueWatchdog', | 
					
						
							|  |  |  |  |         'runInboxQueue', | 
					
						
							|  |  |  |  |         'runPostSchedule', | 
					
						
							|  |  |  |  |         'runPostScheduleWatchdog', | 
					
						
							|  |  |  |  |         'str2bool', | 
					
						
							|  |  |  |  |         'runNewswireDaemon', | 
					
						
							|  |  |  |  |         'runNewswireWatchdog', | 
					
						
							|  |  |  |  |         'threadSendPost', | 
					
						
							|  |  |  |  |         'sendToFollowers', | 
					
						
							|  |  |  |  |         'expireCache', | 
					
						
							|  |  |  |  |         'getMutualsOfPerson', | 
					
						
							|  |  |  |  |         'runPostsQueue', | 
					
						
							|  |  |  |  |         'runSharesExpire', | 
					
						
							|  |  |  |  |         'runPostsWatchdog', | 
					
						
							|  |  |  |  |         'runSharesExpireWatchdog', | 
					
						
							|  |  |  |  |         'getThisWeeksEvents', | 
					
						
							|  |  |  |  |         'getAvailability', | 
					
						
							|  |  |  |  |         'testThreadsFunction', | 
					
						
							|  |  |  |  |         'createServerAlice', | 
					
						
							|  |  |  |  |         'createServerBob', | 
					
						
							|  |  |  |  |         'createServerEve', | 
					
						
							|  |  |  |  |         'E2EEremoveDevice', | 
					
						
							| 
									
										
										
										
											2021-02-10 11:24:34 +00:00
										 |  |  |  |         'setOrganizationScheme', | 
					
						
							| 
									
										
										
										
											2021-03-04 14:36:24 +00:00
										 |  |  |  |         'fill_headers', | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  |  |         '_nothing' | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  |     excludeImports = [ | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         'link', | 
					
						
							|  |  |  |  |         'start' | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |  |     excludeLocal = [ | 
					
						
							|  |  |  |  |         'pyjsonld', | 
					
						
							|  |  |  |  |         'daemon', | 
					
						
							|  |  |  |  |         'tests' | 
					
						
							|  |  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |     excludeMods = [ | 
					
						
							|  |  |  |  |         'pyjsonld' | 
					
						
							|  |  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |     # check that functions are called somewhere | 
					
						
							|  |  |  |  |     for name, properties in functionProperties.items(): | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         if name.startswith('__'): | 
					
						
							|  |  |  |  |             if name.endswith('__'): | 
					
						
							|  |  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |         if name in exclusions: | 
					
						
							|  |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |         if properties['module'] in excludeMods: | 
					
						
							|  |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-12-22 18:20:32 +00:00
										 |  |  |  |         isLocalFunction = False | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |         if not properties['calledInModule']: | 
					
						
							|  |  |  |  |             print('function ' + name + | 
					
						
							|  |  |  |  |                   ' in module ' + properties['module'] + | 
					
						
							|  |  |  |  |                   ' is not called anywhere') | 
					
						
							|  |  |  |  |         assert properties['calledInModule'] | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         if len(properties['calledInModule']) == 1: | 
					
						
							|  |  |  |  |             modName = properties['calledInModule'][0] | 
					
						
							|  |  |  |  |             if modName not in excludeLocal and \ | 
					
						
							|  |  |  |  |                modName == properties['module']: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:20:32 +00:00
										 |  |  |  |                 isLocalFunction = True | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |  |                 if not name.startswith('_'): | 
					
						
							|  |  |  |  |                     print('Local function ' + name + | 
					
						
							| 
									
										
										
										
											2020-12-22 18:16:24 +00:00
										 |  |  |  |                           ' in ' + modName + '.py does not begin with _') | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |  |                     assert False | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  |         if name not in excludeImports: | 
					
						
							|  |  |  |  |             for modName in properties['calledInModule']: | 
					
						
							|  |  |  |  |                 if modName == properties['module']: | 
					
						
							|  |  |  |  |                     continue | 
					
						
							|  |  |  |  |                 importStr = 'from ' + properties['module'] + ' import ' + name | 
					
						
							| 
									
										
										
										
											2020-12-22 19:28:34 +00:00
										 |  |  |  |                 if importStr not in modules[modName]['source']: | 
					
						
							| 
									
										
										
										
											2020-12-22 13:57:24 +00:00
										 |  |  |  |                     print(importStr + ' not found in ' + modName + '.py') | 
					
						
							|  |  |  |  |                     assert False | 
					
						
							| 
									
										
										
										
											2020-12-22 18:16:24 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:20:32 +00:00
										 |  |  |  |         if not isLocalFunction: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:16:24 +00:00
										 |  |  |  |             if name.startswith('_'): | 
					
						
							|  |  |  |  |                 excludePublic = [ | 
					
						
							|  |  |  |  |                     'pyjsonld', | 
					
						
							|  |  |  |  |                     'daemon', | 
					
						
							|  |  |  |  |                     'tests' | 
					
						
							|  |  |  |  |                 ] | 
					
						
							|  |  |  |  |                 modName = properties['module'] | 
					
						
							|  |  |  |  |                 if modName not in excludePublic: | 
					
						
							|  |  |  |  |                     print('Public function ' + name + ' in ' + | 
					
						
							|  |  |  |  |                           modName + '.py begins with _') | 
					
						
							|  |  |  |  |                     assert False | 
					
						
							| 
									
										
										
										
											2020-12-22 13:04:49 +00:00
										 |  |  |  |         print('Function: ' + name + ' ✓') | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-23 16:19:18 +00:00
										 |  |  |  |     print('Constructing function call graph') | 
					
						
							| 
									
										
										
										
											2020-12-23 18:15:30 +00:00
										 |  |  |  |     moduleColors = ('red', 'green', 'yellow', 'orange', 'purple', 'cyan', | 
					
						
							|  |  |  |  |                     'darkgoldenrod3', 'darkolivegreen1', 'darkorange1', | 
					
						
							|  |  |  |  |                     'darkorchid1', 'darkseagreen', 'darkslategray4', | 
					
						
							|  |  |  |  |                     'deeppink1', 'deepskyblue1', 'dimgrey', 'gold1', | 
					
						
							|  |  |  |  |                     'goldenrod', 'burlywood2', 'bisque1', 'brown1', | 
					
						
							|  |  |  |  |                     'chartreuse2', 'cornsilk', 'darksalmon') | 
					
						
							| 
									
										
										
										
											2020-12-23 17:56:25 +00:00
										 |  |  |  |     maxModuleCalls = 1 | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |     maxFunctionCalls = 1 | 
					
						
							| 
									
										
										
										
											2020-12-23 18:15:30 +00:00
										 |  |  |  |     colorCtr = 0 | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |     for modName, modProperties in modules.items(): | 
					
						
							|  |  |  |  |         lineCtr = 0 | 
					
						
							| 
									
										
										
										
											2020-12-23 18:15:30 +00:00
										 |  |  |  |         modules[modName]['color'] = moduleColors[colorCtr] | 
					
						
							|  |  |  |  |         colorCtr += 1 | 
					
						
							|  |  |  |  |         if colorCtr >= len(moduleColors): | 
					
						
							|  |  |  |  |             colorCtr = 0 | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |         for line in modules[modName]['lines']: | 
					
						
							| 
									
										
										
										
											2020-12-23 12:48:50 +00:00
										 |  |  |  |             if line.strip().startswith('def '): | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |                 name = line.split('def ')[1].split('(')[0] | 
					
						
							|  |  |  |  |                 callsList = \ | 
					
						
							|  |  |  |  |                     getFunctionCalls(name, modules[modName]['lines'], | 
					
						
							|  |  |  |  |                                      lineCtr, functionProperties) | 
					
						
							|  |  |  |  |                 functionProperties[name]['calls'] = callsList.copy() | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |                 if len(callsList) > maxFunctionCalls: | 
					
						
							|  |  |  |  |                     maxFunctionCalls = len(callsList) | 
					
						
							| 
									
										
										
										
											2020-12-23 16:19:18 +00:00
										 |  |  |  |                 # keep track of which module calls which other module | 
					
						
							|  |  |  |  |                 for fn in callsList: | 
					
						
							|  |  |  |  |                     modCall = functionProperties[fn]['module'] | 
					
						
							|  |  |  |  |                     if modCall != modName: | 
					
						
							|  |  |  |  |                         if modules[modName].get('calls'): | 
					
						
							|  |  |  |  |                             if modCall not in modules[modName]['calls']: | 
					
						
							|  |  |  |  |                                 modules[modName]['calls'].append(modCall) | 
					
						
							| 
									
										
										
										
											2020-12-23 17:56:25 +00:00
										 |  |  |  |                                 if len(modules[modName]['calls']) > \ | 
					
						
							|  |  |  |  |                                    maxModuleCalls: | 
					
						
							|  |  |  |  |                                     maxModuleCalls = \ | 
					
						
							|  |  |  |  |                                         len(modules[modName]['calls']) | 
					
						
							| 
									
										
										
										
											2020-12-23 16:19:18 +00:00
										 |  |  |  |                         else: | 
					
						
							|  |  |  |  |                             modules[modName]['calls'] = [modCall] | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |             lineCtr += 1 | 
					
						
							| 
									
										
										
										
											2020-12-23 16:19:18 +00:00
										 |  |  |  |     callGraphStr = 'digraph EpicyonModules {\n\n' | 
					
						
							|  |  |  |  |     callGraphStr += '  graph [fontsize=10 fontname="Verdana" compound=true];\n' | 
					
						
							|  |  |  |  |     callGraphStr += '  node [shape=record fontsize=10 fontname="Verdana"];\n\n' | 
					
						
							| 
									
										
										
										
											2020-12-23 17:56:25 +00:00
										 |  |  |  |     # colors of modules nodes | 
					
						
							|  |  |  |  |     for modName, modProperties in modules.items(): | 
					
						
							|  |  |  |  |         if not modProperties.get('calls'): | 
					
						
							|  |  |  |  |             callGraphStr += '  "' + modName + \ | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |                 '" [fillcolor=yellow style=filled];\n' | 
					
						
							| 
									
										
										
										
											2020-12-23 17:56:25 +00:00
										 |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |         if len(modProperties['calls']) <= int(maxModuleCalls / 8): | 
					
						
							| 
									
										
										
										
											2020-12-23 17:56:25 +00:00
										 |  |  |  |             callGraphStr += '  "' + modName + \ | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |                 '" [fillcolor=green style=filled];\n' | 
					
						
							|  |  |  |  |         elif len(modProperties['calls']) < int(maxModuleCalls / 4): | 
					
						
							|  |  |  |  |             callGraphStr += '  "' + modName + \ | 
					
						
							|  |  |  |  |                 '" [fillcolor=orange style=filled];\n' | 
					
						
							| 
									
										
										
										
											2020-12-23 17:56:25 +00:00
										 |  |  |  |         else: | 
					
						
							|  |  |  |  |             callGraphStr += '  "' + modName + \ | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |                 '" [fillcolor=red style=filled];\n' | 
					
						
							| 
									
										
										
										
											2020-12-23 17:56:25 +00:00
										 |  |  |  |     callGraphStr += '\n' | 
					
						
							|  |  |  |  |     # connections between modules | 
					
						
							| 
									
										
										
										
											2020-12-23 16:19:18 +00:00
										 |  |  |  |     for modName, modProperties in modules.items(): | 
					
						
							|  |  |  |  |         if not modProperties.get('calls'): | 
					
						
							|  |  |  |  |             continue | 
					
						
							|  |  |  |  |         for modCall in modProperties['calls']: | 
					
						
							|  |  |  |  |             callGraphStr += '  "' + modName + '" -> "' + modCall + '";\n' | 
					
						
							|  |  |  |  |     callGraphStr += '\n}\n' | 
					
						
							|  |  |  |  |     with open('epicyon_modules.dot', 'w+') as fp: | 
					
						
							|  |  |  |  |         fp.write(callGraphStr) | 
					
						
							|  |  |  |  |         print('Modules call graph saved to epicyon_modules.dot') | 
					
						
							|  |  |  |  |         print('Plot using: ' + | 
					
						
							|  |  |  |  |               'sfdp -x -Goverlap=false -Goverlap_scaling=2 ' + | 
					
						
							|  |  |  |  |               '-Gsep=+100 -Tx11 epicyon_modules.dot') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |     callGraphStr = 'digraph Epicyon {\n\n' | 
					
						
							| 
									
										
										
										
											2020-12-23 16:19:18 +00:00
										 |  |  |  |     callGraphStr += '  size="8,6"; ratio=fill;\n' | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |     callGraphStr += '  graph [fontsize=10 fontname="Verdana" compound=true];\n' | 
					
						
							|  |  |  |  |     callGraphStr += '  node [shape=record fontsize=10 fontname="Verdana"];\n\n' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     for modName, modProperties in modules.items(): | 
					
						
							| 
									
										
										
										
											2020-12-22 23:26:09 +00:00
										 |  |  |  |         callGraphStr += '  subgraph cluster_' + modName + ' {\n' | 
					
						
							|  |  |  |  |         callGraphStr += '    label = "' + modName + '";\n' | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |         callGraphStr += '    node [style=filled];\n' | 
					
						
							| 
									
										
										
										
											2020-12-23 13:41:54 +00:00
										 |  |  |  |         moduleFunctionsStr = '' | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |         for name in modProperties['functions']: | 
					
						
							| 
									
										
										
										
											2020-12-23 14:19:06 +00:00
										 |  |  |  |             if name.startswith('test'): | 
					
						
							|  |  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-12-23 13:41:54 +00:00
										 |  |  |  |             if name not in excludeFuncs: | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |                 if not functionProperties[name]['calls']: | 
					
						
							|  |  |  |  |                     moduleFunctionsStr += \ | 
					
						
							|  |  |  |  |                         '  "' + name + '" [fillcolor=yellow style=filled];\n' | 
					
						
							|  |  |  |  |                     continue | 
					
						
							|  |  |  |  |                 noOfCalls = len(functionProperties[name]['calls']) | 
					
						
							|  |  |  |  |                 if noOfCalls < int(maxFunctionCalls / 4): | 
					
						
							|  |  |  |  |                     moduleFunctionsStr += '  "' + name + \ | 
					
						
							|  |  |  |  |                         '" [fillcolor=orange style=filled];\n' | 
					
						
							|  |  |  |  |                 else: | 
					
						
							|  |  |  |  |                     moduleFunctionsStr += '  "' + name + \ | 
					
						
							|  |  |  |  |                         '" [fillcolor=red style=filled];\n' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-23 13:41:54 +00:00
										 |  |  |  |         if moduleFunctionsStr: | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |             callGraphStr += moduleFunctionsStr + '\n' | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  |         callGraphStr += '    color=blue;\n' | 
					
						
							|  |  |  |  |         callGraphStr += '  }\n\n' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     for name, properties in functionProperties.items(): | 
					
						
							|  |  |  |  |         if not properties['calls']: | 
					
						
							|  |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-12-23 19:55:51 +00:00
										 |  |  |  |         noOfCalls = len(properties['calls']) | 
					
						
							|  |  |  |  |         if noOfCalls <= int(maxFunctionCalls / 8): | 
					
						
							|  |  |  |  |             modColor = 'blue' | 
					
						
							|  |  |  |  |         elif noOfCalls < int(maxFunctionCalls / 4): | 
					
						
							|  |  |  |  |             modColor = 'green' | 
					
						
							|  |  |  |  |         else: | 
					
						
							|  |  |  |  |             modColor = 'red' | 
					
						
							| 
									
										
										
										
											2020-12-22 23:26:09 +00:00
										 |  |  |  |         for calledFunc in properties['calls']: | 
					
						
							| 
									
										
										
										
											2020-12-23 14:19:06 +00:00
										 |  |  |  |             if calledFunc.startswith('test'): | 
					
						
							|  |  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-12-23 13:41:54 +00:00
										 |  |  |  |             if calledFunc not in excludeFuncs: | 
					
						
							| 
									
										
										
										
											2020-12-23 18:15:30 +00:00
										 |  |  |  |                 callGraphStr += '  "' + name + '" -> "' + calledFunc + \ | 
					
						
							|  |  |  |  |                     '" [color=' + modColor + '];\n' | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     callGraphStr += '\n}\n' | 
					
						
							|  |  |  |  |     with open('epicyon.dot', 'w+') as fp: | 
					
						
							|  |  |  |  |         fp.write(callGraphStr) | 
					
						
							|  |  |  |  |         print('Call graph saved to epicyon.dot') | 
					
						
							| 
									
										
										
										
											2020-12-23 16:19:18 +00:00
										 |  |  |  |         print('Plot using: ' + | 
					
						
							| 
									
										
										
										
											2020-12-23 13:41:54 +00:00
										 |  |  |  |               'sfdp -x -Goverlap=prism -Goverlap_scaling=8 ' + | 
					
						
							|  |  |  |  |               '-Gsep=+120 -Tx11 epicyon.dot') | 
					
						
							| 
									
										
										
										
											2020-12-22 22:55:45 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-02 10:37:19 +00:00
										 |  |  |  | def testLinksWithinPost() -> None: | 
					
						
							|  |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     nickname = 'test27636' | 
					
						
							|  |  |  |  |     domain = 'rando.site' | 
					
						
							|  |  |  |  |     port = 443 | 
					
						
							|  |  |  |  |     httpPrefix = 'https' | 
					
						
							|  |  |  |  |     content = 'This is a test post with links.\n\n' + \ | 
					
						
							|  |  |  |  |         'ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/v4/\n\nhttps://freedombone.net' | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     followersOnly = False | 
					
						
							|  |  |  |  |     saveToFile = False | 
					
						
							|  |  |  |  |     clientToServer = False | 
					
						
							|  |  |  |  |     commentsEnabled = True | 
					
						
							|  |  |  |  |     mediaType = None | 
					
						
							|  |  |  |  |     imageDescription = None | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     city = 'London, England' | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-02 10:37:19 +00:00
										 |  |  |  |     postJsonObject = \ | 
					
						
							|  |  |  |  |         createPublicPost(baseDir, nickname, domain, port, httpPrefix, | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |                          content, followersOnly, saveToFile, | 
					
						
							|  |  |  |  |                          clientToServer, commentsEnabled, | 
					
						
							|  |  |  |  |                          mediaType, imageDescription, city, | 
					
						
							|  |  |  |  |                          False, None) | 
					
						
							| 
									
										
										
										
											2021-01-02 10:37:19 +00:00
										 |  |  |  |     assert postJsonObject['object']['content'] == \ | 
					
						
							|  |  |  |  |         '<p>This is a test post with links.<br><br>' + \ | 
					
						
							|  |  |  |  |         '<a href="ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/v4/" ' + \ | 
					
						
							|  |  |  |  |         'rel="nofollow noopener noreferrer" target="_blank">' + \ | 
					
						
							|  |  |  |  |         '<span class="invisible">ftp://</span>' + \ | 
					
						
							|  |  |  |  |         '<span class="ellipsis">' + \ | 
					
						
							|  |  |  |  |         'ftp.ncdc.noaa.gov/pub/data/ghcn/v4/</span>' + \ | 
					
						
							|  |  |  |  |         '</a><br><br><a href="https://freedombone.net" ' + \ | 
					
						
							|  |  |  |  |         'rel="nofollow noopener noreferrer" target="_blank">' + \ | 
					
						
							|  |  |  |  |         '<span class="invisible">https://</span>' + \ | 
					
						
							|  |  |  |  |         '<span class="ellipsis">freedombone.net</span></a></p>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-05 23:09:04 +00:00
										 |  |  |  |     content = "<p>Some text</p><p>Other text</p><p>More text</p>" + \ | 
					
						
							|  |  |  |  |         "<pre><code>Errno::EOHNOES (No such file or rodent @ " + \ | 
					
						
							|  |  |  |  |         "ik_right - /tmp/blah.png)<br></code></pre><p>" + \ | 
					
						
							|  |  |  |  |         "(<a href=\"https://welllookeyhere.maam/error.txt\" " + \ | 
					
						
							|  |  |  |  |         "rel=\"nofollow noopener noreferrer\" target=\"_blank\">" + \ | 
					
						
							|  |  |  |  |         "wuh</a>)</p><p>Oh yeah like for sure</p>" + \ | 
					
						
							|  |  |  |  |         "<p>Ground sloth tin opener</p>" + \ | 
					
						
							|  |  |  |  |         "<p><a href=\"https://whocodedthis.huh/tags/" + \ | 
					
						
							|  |  |  |  |         "taggedthing\" class=\"mention hashtag\" rel=\"tag\" " + \ | 
					
						
							|  |  |  |  |         "target=\"_blank\">#<span>taggedthing</span></a></p>" | 
					
						
							|  |  |  |  |     postJsonObject = \ | 
					
						
							|  |  |  |  |         createPublicPost(baseDir, nickname, domain, port, httpPrefix, | 
					
						
							|  |  |  |  |                          content, | 
					
						
							|  |  |  |  |                          False, False, False, True, | 
					
						
							|  |  |  |  |                          None, None, False, None) | 
					
						
							|  |  |  |  |     assert postJsonObject['object']['content'] == content | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-02 10:37:19 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 13:32:37 +00:00
										 |  |  |  | def testMastoApi(): | 
					
						
							|  |  |  |  |     print('testMastoApi') | 
					
						
							|  |  |  |  |     nickname = 'ThisIsATestNickname' | 
					
						
							|  |  |  |  |     mastoId = getMastoApiV1IdFromNickname(nickname) | 
					
						
							|  |  |  |  |     assert(mastoId) | 
					
						
							|  |  |  |  |     nickname2 = getNicknameFromMastoApiV1Id(mastoId) | 
					
						
							|  |  |  |  |     if nickname2 != nickname: | 
					
						
							|  |  |  |  |         print(nickname + ' != ' + nickname2) | 
					
						
							|  |  |  |  |     assert nickname2 == nickname | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 12:24:40 +00:00
										 |  |  |  | def testDomainHandling(): | 
					
						
							|  |  |  |  |     print('testDomainHandling') | 
					
						
							|  |  |  |  |     testDomain = 'localhost' | 
					
						
							|  |  |  |  |     assert decodedHost(testDomain) == testDomain | 
					
						
							|  |  |  |  |     testDomain = '127.0.0.1:60' | 
					
						
							|  |  |  |  |     assert decodedHost(testDomain) == testDomain | 
					
						
							|  |  |  |  |     testDomain = '192.168.5.153' | 
					
						
							|  |  |  |  |     assert decodedHost(testDomain) == testDomain | 
					
						
							|  |  |  |  |     testDomain = 'xn--espaa-rta.icom.museum' | 
					
						
							|  |  |  |  |     assert decodedHost(testDomain) == "españa.icom.museum" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-02 21:08:33 +00:00
										 |  |  |  | def testPrepareHtmlPostNickname(): | 
					
						
							|  |  |  |  |     print('testPrepareHtmlPostNickname') | 
					
						
							|  |  |  |  |     postHtml = '<a class="imageAnchor" href="/users/bob?replyfollowers=' | 
					
						
							|  |  |  |  |     postHtml += '<a class="imageAnchor" href="/users/bob?repeatprivate=' | 
					
						
							|  |  |  |  |     result = prepareHtmlPostNickname('alice', postHtml) | 
					
						
							|  |  |  |  |     assert result == postHtml.replace('/bob?', '/alice?') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     postHtml = '<a class="imageAnchor" href="/users/bob?replyfollowers=' | 
					
						
							|  |  |  |  |     postHtml += '<a class="imageAnchor" href="/users/bob;repeatprivate=' | 
					
						
							|  |  |  |  |     expectedHtml = '<a class="imageAnchor" href="/users/alice?replyfollowers=' | 
					
						
							|  |  |  |  |     expectedHtml += '<a class="imageAnchor" href="/users/bob;repeatprivate=' | 
					
						
							|  |  |  |  |     result = prepareHtmlPostNickname('alice', postHtml) | 
					
						
							|  |  |  |  |     assert result == expectedHtml | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-09 13:28:42 +00:00
										 |  |  |  | def testValidHashTag(): | 
					
						
							|  |  |  |  |     print('testValidHashTag') | 
					
						
							|  |  |  |  |     assert validHashTag('ThisIsValid') | 
					
						
							|  |  |  |  |     assert validHashTag('ThisIsValid12345') | 
					
						
							|  |  |  |  |     assert validHashTag('ThisIsVälid') | 
					
						
							| 
									
										
										
										
											2021-02-09 14:41:32 +00:00
										 |  |  |  |     assert validHashTag('यहमान्यहै') | 
					
						
							| 
									
										
										
										
											2021-02-09 13:28:42 +00:00
										 |  |  |  |     assert not validHashTag('ThisIsNotValid!') | 
					
						
							|  |  |  |  |     assert not validHashTag('#ThisIsAlsoNotValid') | 
					
						
							| 
									
										
										
										
											2021-02-09 14:41:32 +00:00
										 |  |  |  |     assert not validHashTag('#यहमान्यहै') | 
					
						
							| 
									
										
										
										
											2021-02-09 13:28:42 +00:00
										 |  |  |  |     assert not validHashTag('ThisIsAlso&NotValid') | 
					
						
							|  |  |  |  |     assert not validHashTag('ThisIsAlsoNotValid"') | 
					
						
							| 
									
										
										
										
											2021-02-09 14:41:32 +00:00
										 |  |  |  |     assert not validHashTag('This Is Also Not Valid"') | 
					
						
							| 
									
										
										
										
											2021-02-09 13:28:42 +00:00
										 |  |  |  |     assert not validHashTag('This=IsAlsoNotValid"') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  | def testMarkdownToHtml(): | 
					
						
							|  |  |  |  |     print('testMarkdownToHtml') | 
					
						
							|  |  |  |  |     markdown = 'This is just plain text' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == markdown | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-26 23:00:06 +00:00
										 |  |  |  |     markdown = 'This is a quotation:\n' + \ | 
					
						
							|  |  |  |  |         '> Some quote or other' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == 'This is a quotation:<br>' + \ | 
					
						
							|  |  |  |  |         '<blockquote><i>Some quote or other</i></blockquote>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-26 23:13:33 +00:00
										 |  |  |  |     markdown = 'This is a multi-line quotation:\n' + \ | 
					
						
							|  |  |  |  |         '> The first line\n' + \ | 
					
						
							|  |  |  |  |         '> The second line' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == \ | 
					
						
							|  |  |  |  |         'This is a multi-line quotation:<br>' + \ | 
					
						
							|  |  |  |  |         '<blockquote><i>The first line The second line</i></blockquote>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-25 10:54:38 +00:00
										 |  |  |  |     markdown = 'This is **bold**' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == 'This is <b>bold</b>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     markdown = 'This is *italic*' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == 'This is <i>italic</i>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     markdown = 'This is _underlined_' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == 'This is <ul>underlined</ul>' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     markdown = 'This is **just** plain text' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == 'This is <b>just</b> plain text' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  |     markdown = '# Title1\n### Title3\n## Title2\n' | 
					
						
							|  |  |  |  |     assert markdownToHtml(markdown) == \ | 
					
						
							| 
									
										
										
										
											2021-02-24 21:17:08 +00:00
										 |  |  |  |         '<h1>Title1</h1><h3>Title3</h3><h2>Title2</h2>' | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     markdown = \ | 
					
						
							| 
									
										
										
										
											2021-02-25 10:54:38 +00:00
										 |  |  |  |         'This is [a link](https://something.somewhere) to something.\n' + \ | 
					
						
							| 
									
										
										
										
											2021-02-26 15:20:43 +00:00
										 |  |  |  |         'And [something else](https://cat.pic).\n' + \ | 
					
						
							|  |  |  |  |         'Or .' | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  |     assert markdownToHtml(markdown) == \ | 
					
						
							|  |  |  |  |         'This is <a href="https://something.somewhere" ' + \ | 
					
						
							|  |  |  |  |         'target="_blank" rel="nofollow noopener noreferrer">' + \ | 
					
						
							| 
									
										
										
										
											2021-02-25 10:54:38 +00:00
										 |  |  |  |         'a link</a> to something.<br>' + \ | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  |         'And <a href="https://cat.pic" ' + \ | 
					
						
							|  |  |  |  |         'target="_blank" rel="nofollow noopener noreferrer">' + \ | 
					
						
							| 
									
										
										
										
											2021-02-26 15:20:43 +00:00
										 |  |  |  |         'something else</a>.<br>' + \ | 
					
						
							|  |  |  |  |         'Or <img class="markdownImage" src="/cat.jpg" alt="pounce" />.' | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-01 10:02:55 +00:00
										 |  |  |  | def testExtractTextFieldsInPOST(): | 
					
						
							|  |  |  |  |     print('testExtractTextFieldsInPOST') | 
					
						
							|  |  |  |  |     boundary = '-----------------------------116202748023898664511855843036' | 
					
						
							|  |  |  |  |     formData = '-----------------------------116202748023898664511855' + \ | 
					
						
							|  |  |  |  |         '843036\r\nContent-Disposition: form-data; name="submitPost"' + \ | 
					
						
							|  |  |  |  |         '\r\n\r\nSubmit\r\n-----------------------------116202748023' + \ | 
					
						
							|  |  |  |  |         '898664511855843036\r\nContent-Disposition: form-data; name=' + \ | 
					
						
							|  |  |  |  |         '"subject"\r\n\r\n\r\n-----------------------------116202748' + \ | 
					
						
							|  |  |  |  |         '023898664511855843036\r\nContent-Disposition: form-data; na' + \ | 
					
						
							|  |  |  |  |         'me="message"\r\n\r\nThis is a ; test\r\n-------------------' + \ | 
					
						
							|  |  |  |  |         '----------116202748023898664511855843036\r\nContent-Disposi' + \ | 
					
						
							|  |  |  |  |         'tion: form-data; name="commentsEnabled"\r\n\r\non\r\n------' + \ | 
					
						
							|  |  |  |  |         '-----------------------116202748023898664511855843036\r\nCo' + \ | 
					
						
							|  |  |  |  |         'ntent-Disposition: form-data; name="eventDate"\r\n\r\n\r\n' + \ | 
					
						
							|  |  |  |  |         '-----------------------------116202748023898664511855843036' + \ | 
					
						
							|  |  |  |  |         '\r\nContent-Disposition: form-data; name="eventTime"\r\n\r' + \ | 
					
						
							|  |  |  |  |         '\n\r\n-----------------------------116202748023898664511855' + \ | 
					
						
							|  |  |  |  |         '843036\r\nContent-Disposition: form-data; name="location"' + \ | 
					
						
							|  |  |  |  |         '\r\n\r\n\r\n-----------------------------116202748023898664' + \ | 
					
						
							|  |  |  |  |         '511855843036\r\nContent-Disposition: form-data; name=' + \ | 
					
						
							|  |  |  |  |         '"imageDescription"\r\n\r\n\r\n-----------------------------' + \ | 
					
						
							|  |  |  |  |         '116202748023898664511855843036\r\nContent-Disposition: ' + \ | 
					
						
							|  |  |  |  |         'form-data; name="attachpic"; filename=""\r\nContent-Type: ' + \ | 
					
						
							|  |  |  |  |         'application/octet-stream\r\n\r\n\r\n----------------------' + \ | 
					
						
							|  |  |  |  |         '-------116202748023898664511855843036--\r\n' | 
					
						
							|  |  |  |  |     debug = False | 
					
						
							|  |  |  |  |     fields = extractTextFieldsInPOST(None, boundary, debug, formData) | 
					
						
							|  |  |  |  |     assert fields['submitPost'] == 'Submit' | 
					
						
							|  |  |  |  |     assert fields['subject'] == '' | 
					
						
							|  |  |  |  |     assert fields['commentsEnabled'] == 'on' | 
					
						
							|  |  |  |  |     assert fields['eventDate'] == '' | 
					
						
							|  |  |  |  |     assert fields['eventTime'] == '' | 
					
						
							|  |  |  |  |     assert fields['location'] == '' | 
					
						
							|  |  |  |  |     assert fields['imageDescription'] == '' | 
					
						
							|  |  |  |  |     assert fields['message'] == 'This is a ; test' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-01 21:46:44 +00:00
										 |  |  |  | def testSpeakerReplaceLinks(): | 
					
						
							|  |  |  |  |     print('testSpeakerReplaceLinks') | 
					
						
							|  |  |  |  |     text = 'The Tor Project: For Snowflake volunteers: If you use ' + \ | 
					
						
							|  |  |  |  |         'Firefox, Brave, or Chrome, our Snowflake extension turns ' + \ | 
					
						
							|  |  |  |  |         'your browser into a proxy that connects Tor users in ' + \ | 
					
						
							|  |  |  |  |         'censored regions to the Tor network. Note: you should ' + \ | 
					
						
							|  |  |  |  |         'not run more than one snowflake in the same ' + \ | 
					
						
							|  |  |  |  |         'network.https://support.torproject.org/censorship/' + \ | 
					
						
							|  |  |  |  |         'how-to-help-running-snowflake/' | 
					
						
							|  |  |  |  |     detectedLinks = [] | 
					
						
							|  |  |  |  |     result = speakerReplaceLinks(text, {'Linked': 'Web link'}, detectedLinks) | 
					
						
							|  |  |  |  |     assert len(detectedLinks) == 1 | 
					
						
							|  |  |  |  |     assert detectedLinks[0] == \ | 
					
						
							|  |  |  |  |         'https://support.torproject.org/censorship/' + \ | 
					
						
							|  |  |  |  |         'how-to-help-running-snowflake/' | 
					
						
							|  |  |  |  |     assert 'Web link support.torproject.org' in result | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 20:34:55 +00:00
										 |  |  |  | def testCamelCaseSplit(): | 
					
						
							|  |  |  |  |     print('testCamelCaseSplit') | 
					
						
							|  |  |  |  |     testStr = 'ThisIsCamelCase' | 
					
						
							|  |  |  |  |     assert camelCaseSplit(testStr) == 'This Is Camel Case' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     testStr = 'Notcamelcase test' | 
					
						
							|  |  |  |  |     assert camelCaseSplit(testStr) == 'Notcamelcase test' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-08 18:47:55 +00:00
										 |  |  |  | def testEmojiImages(): | 
					
						
							|  |  |  |  |     print('testEmojiImages') | 
					
						
							|  |  |  |  |     emojiFilename = 'emoji/default_emoji.json' | 
					
						
							|  |  |  |  |     assert os.path.isfile(emojiFilename) | 
					
						
							|  |  |  |  |     emojiJson = loadJson(emojiFilename) | 
					
						
							|  |  |  |  |     assert emojiJson | 
					
						
							|  |  |  |  |     for emojiName, emojiImage in emojiJson.items(): | 
					
						
							|  |  |  |  |         emojiImageFilename = 'emoji/' + emojiImage + '.png' | 
					
						
							|  |  |  |  |         if not os.path.isfile(emojiImageFilename): | 
					
						
							|  |  |  |  |             print('Missing emoji image ' + emojiName + ' ' + | 
					
						
							|  |  |  |  |                   emojiImage + '.png') | 
					
						
							|  |  |  |  |         assert os.path.isfile(emojiImageFilename) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |  | def testExtractPGPPublicKey(): | 
					
						
							|  |  |  |  |     print('testExtractPGPPublicKey') | 
					
						
							|  |  |  |  |     pubKey = \ | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |  |         '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n' + \ | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |  |         'mDMEWZBueBYJKwYBBAHaRw8BAQdAKx1t6wL0RTuU6/' + \ | 
					
						
							|  |  |  |  |         'IBjngMbVJJ3Wg/3UW73/PV\n' + \ | 
					
						
							|  |  |  |  |         'I47xKTS0IUJvYiBNb3R0cmFtIDxib2JAZnJlZWRvb' + \ | 
					
						
							|  |  |  |  |         'WJvbmUubmV0PoiQBBMWCAA4\n' + \ | 
					
						
							|  |  |  |  |         'FiEEmruCwAq/OfgmgEh9zCU2GR+nwz8FAlmQbngCG' + \ | 
					
						
							|  |  |  |  |         'wMFCwkIBwMFFQoJCAsFFgID\n' + \ | 
					
						
							|  |  |  |  |         'AQACHgECF4AACgkQzCU2GR+nwz/9sAD/YgsHnVszH' + \ | 
					
						
							|  |  |  |  |         'Nz1zlVc5EgY1ByDupiJpHj0\n' + \ | 
					
						
							|  |  |  |  |         'XsLYk3AbNRgBALn45RqgD4eWHpmOriH09H5Rc5V9i' + \ | 
					
						
							|  |  |  |  |         'N4+OiGUn2AzJ6oHuDgEWZBu\n' + \ | 
					
						
							|  |  |  |  |         'eBIKKwYBBAGXVQEFAQEHQPRBG2ZQJce475S3e0Dxe' + \ | 
					
						
							|  |  |  |  |         'b0Fz5WdEu2q3GYLo4QG+4Ry\n' + \ | 
					
						
							|  |  |  |  |         'AwEIB4h4BBgWCAAgFiEEmruCwAq/OfgmgEh9zCU2G' + \ | 
					
						
							|  |  |  |  |         'R+nwz8FAlmQbngCGwwACgkQ\n' + \ | 
					
						
							|  |  |  |  |         'zCU2GR+nwz+OswD+JOoyBku9FzuWoVoOevU2HH+bP' + \ | 
					
						
							|  |  |  |  |         'OMDgY2OLnST9ZSyHkMBAMcK\n' + \ | 
					
						
							|  |  |  |  |         'fnaZ2Wi050483Sj2RmQRpb99Dod7rVZTDtCqXk0J\n' + \ | 
					
						
							|  |  |  |  |         '=gv5G\n' + \ | 
					
						
							|  |  |  |  |         '-----END PGP PUBLIC KEY BLOCK-----' | 
					
						
							|  |  |  |  |     testStr = "Some introduction\n\n" + pubKey + "\n\nSome message." | 
					
						
							| 
									
										
										
										
											2021-03-12 09:50:08 +00:00
										 |  |  |  |     assert containsPGPPublicKey(testStr) | 
					
						
							|  |  |  |  |     assert not containsPGPPublicKey('String without a pgp key') | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |  |     result = extractPGPPublicKey(testStr) | 
					
						
							|  |  |  |  |     assert result | 
					
						
							|  |  |  |  |     assert result == pubKey | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |  | def testUpdateActor(): | 
					
						
							|  |  |  |  |     print('Testing update of actor properties') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     global testServerAliceRunning | 
					
						
							|  |  |  |  |     testServerAliceRunning = False | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     httpPrefix = 'http' | 
					
						
							|  |  |  |  |     proxyType = None | 
					
						
							|  |  |  |  |     federationList = [] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     baseDir = os.getcwd() | 
					
						
							|  |  |  |  |     if os.path.isdir(baseDir + '/.tests'): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir + '/.tests') | 
					
						
							|  |  |  |  |     os.mkdir(baseDir + '/.tests') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # create the server | 
					
						
							|  |  |  |  |     aliceDir = baseDir + '/.tests/alice' | 
					
						
							|  |  |  |  |     aliceDomain = '127.0.0.11' | 
					
						
							|  |  |  |  |     alicePort = 61792 | 
					
						
							|  |  |  |  |     aliceSendThreads = [] | 
					
						
							|  |  |  |  |     bobAddress = '127.0.0.84:6384' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     global thrAlice | 
					
						
							|  |  |  |  |     if thrAlice: | 
					
						
							|  |  |  |  |         while thrAlice.is_alive(): | 
					
						
							|  |  |  |  |             thrAlice.stop() | 
					
						
							|  |  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |  |         thrAlice.kill() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrAlice = \ | 
					
						
							|  |  |  |  |         threadWithTrace(target=createServerAlice, | 
					
						
							|  |  |  |  |                         args=(aliceDir, aliceDomain, alicePort, bobAddress, | 
					
						
							|  |  |  |  |                               federationList, False, False, | 
					
						
							|  |  |  |  |                               aliceSendThreads), | 
					
						
							|  |  |  |  |                         daemon=True) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     thrAlice.start() | 
					
						
							|  |  |  |  |     assert thrAlice.is_alive() is True | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # wait for server to be running | 
					
						
							|  |  |  |  |     ctr = 0 | 
					
						
							|  |  |  |  |     while not testServerAliceRunning: | 
					
						
							|  |  |  |  |         time.sleep(1) | 
					
						
							|  |  |  |  |         ctr += 1 | 
					
						
							|  |  |  |  |         if ctr > 60: | 
					
						
							|  |  |  |  |             break | 
					
						
							|  |  |  |  |     print('Alice online: ' + str(testServerAliceRunning)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     print('\n\n*******************************************************') | 
					
						
							|  |  |  |  |     print('Alice updates her PGP key') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     sessionAlice = createSession(proxyType) | 
					
						
							|  |  |  |  |     cachedWebfingers = {} | 
					
						
							|  |  |  |  |     personCache = {} | 
					
						
							|  |  |  |  |     password = 'alicepass' | 
					
						
							|  |  |  |  |     outboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/outbox' | 
					
						
							|  |  |  |  |     actorFilename = aliceDir + '/accounts/' + 'alice@' + aliceDomain + '.json' | 
					
						
							|  |  |  |  |     assert os.path.isfile(actorFilename) | 
					
						
							|  |  |  |  |     assert len([name for name in os.listdir(outboxPath) | 
					
						
							|  |  |  |  |                 if os.path.isfile(os.path.join(outboxPath, name))]) == 0 | 
					
						
							|  |  |  |  |     pubKey = \ | 
					
						
							|  |  |  |  |         '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n' + \ | 
					
						
							|  |  |  |  |         'mDMEWZBueBYJKwYBBAHaRw8BAQdAKx1t6wL0RTuU6/' + \ | 
					
						
							|  |  |  |  |         'IBjngMbVJJ3Wg/3UW73/PV\n' + \ | 
					
						
							|  |  |  |  |         'I47xKTS0IUJvYiBNb3R0cmFtIDxib2JAZnJlZWRvb' + \ | 
					
						
							|  |  |  |  |         'WJvbmUubmV0PoiQBBMWCAA4\n' + \ | 
					
						
							|  |  |  |  |         'FiEEmruCwAq/OfgmgEh9zCU2GR+nwz8FAlmQbngCG' + \ | 
					
						
							|  |  |  |  |         'wMFCwkIBwMFFQoJCAsFFgID\n' + \ | 
					
						
							|  |  |  |  |         'AQACHgECF4AACgkQzCU2GR+nwz/9sAD/YgsHnVszH' + \ | 
					
						
							|  |  |  |  |         'Nz1zlVc5EgY1ByDupiJpHj0\n' + \ | 
					
						
							|  |  |  |  |         'XsLYk3AbNRgBALn45RqgD4eWHpmOriH09H5Rc5V9i' + \ | 
					
						
							|  |  |  |  |         'N4+OiGUn2AzJ6oHuDgEWZBu\n' + \ | 
					
						
							|  |  |  |  |         'eBIKKwYBBAGXVQEFAQEHQPRBG2ZQJce475S3e0Dxe' + \ | 
					
						
							|  |  |  |  |         'b0Fz5WdEu2q3GYLo4QG+4Ry\n' + \ | 
					
						
							|  |  |  |  |         'AwEIB4h4BBgWCAAgFiEEmruCwAq/OfgmgEh9zCU2G' + \ | 
					
						
							|  |  |  |  |         'R+nwz8FAlmQbngCGwwACgkQ\n' + \ | 
					
						
							|  |  |  |  |         'zCU2GR+nwz+OswD+JOoyBku9FzuWoVoOevU2HH+bP' + \ | 
					
						
							|  |  |  |  |         'OMDgY2OLnST9ZSyHkMBAMcK\n' + \ | 
					
						
							|  |  |  |  |         'fnaZ2Wi050483Sj2RmQRpb99Dod7rVZTDtCqXk0J\n' + \ | 
					
						
							|  |  |  |  |         '=gv5G\n' + \ | 
					
						
							|  |  |  |  |         '-----END PGP PUBLIC KEY BLOCK-----' | 
					
						
							|  |  |  |  |     actorUpdate = \ | 
					
						
							|  |  |  |  |         pgpPublicKeyUpload(aliceDir, sessionAlice, | 
					
						
							|  |  |  |  |                            'alice', password, | 
					
						
							|  |  |  |  |                            aliceDomain, alicePort, | 
					
						
							|  |  |  |  |                            httpPrefix, | 
					
						
							|  |  |  |  |                            cachedWebfingers, personCache, | 
					
						
							|  |  |  |  |                            True, pubKey) | 
					
						
							|  |  |  |  |     print('actor update result: ' + str(actorUpdate)) | 
					
						
							|  |  |  |  |     assert actorUpdate | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # load alice actor | 
					
						
							|  |  |  |  |     print('Loading actor: ' + actorFilename) | 
					
						
							|  |  |  |  |     actorJson = loadJson(actorFilename) | 
					
						
							|  |  |  |  |     assert actorJson | 
					
						
							|  |  |  |  |     if len(actorJson['attachment']) == 0: | 
					
						
							|  |  |  |  |         print("actorJson['attachment'] has no contents") | 
					
						
							|  |  |  |  |     assert len(actorJson['attachment']) > 0 | 
					
						
							|  |  |  |  |     propertyFound = False | 
					
						
							|  |  |  |  |     for propertyValue in actorJson['attachment']: | 
					
						
							|  |  |  |  |         if propertyValue['name'] == 'PGP': | 
					
						
							|  |  |  |  |             print('PGP property set within attachment') | 
					
						
							|  |  |  |  |             assert pubKey in propertyValue['value'] | 
					
						
							|  |  |  |  |             propertyFound = True | 
					
						
							|  |  |  |  |     assert propertyFound | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # stop the server | 
					
						
							|  |  |  |  |     thrAlice.kill() | 
					
						
							|  |  |  |  |     thrAlice.join() | 
					
						
							|  |  |  |  |     assert thrAlice.is_alive() is False | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     os.chdir(baseDir) | 
					
						
							|  |  |  |  |     if os.path.isdir(baseDir + '/.tests'): | 
					
						
							|  |  |  |  |         shutil.rmtree(baseDir + '/.tests') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-30 11:45:46 +00:00
										 |  |  |  | def testRemovePostInteractions() -> None: | 
					
						
							|  |  |  |  |     print('testRemovePostInteractions') | 
					
						
							|  |  |  |  |     postJsonObject = { | 
					
						
							|  |  |  |  |         "type": "Create", | 
					
						
							|  |  |  |  |         "object": { | 
					
						
							|  |  |  |  |             "to": ["#Public"], | 
					
						
							|  |  |  |  |             "likes": { | 
					
						
							|  |  |  |  |                 "items": ["a", "b", "c"] | 
					
						
							|  |  |  |  |             }, | 
					
						
							|  |  |  |  |             "replies": { | 
					
						
							|  |  |  |  |                 "replyStuff": ["a", "b", "c"] | 
					
						
							|  |  |  |  |             }, | 
					
						
							|  |  |  |  |             "shares": { | 
					
						
							|  |  |  |  |                 "sharesStuff": ["a", "b", "c"] | 
					
						
							|  |  |  |  |             }, | 
					
						
							|  |  |  |  |             "bookmarks": { | 
					
						
							|  |  |  |  |                 "bookmarksStuff": ["a", "b", "c"] | 
					
						
							|  |  |  |  |             }, | 
					
						
							|  |  |  |  |             "ignores": { | 
					
						
							|  |  |  |  |                 "ignoresStuff": ["a", "b", "c"] | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     removePostInteractions(postJsonObject, True) | 
					
						
							|  |  |  |  |     assert postJsonObject['object']['likes']['items'] == [] | 
					
						
							|  |  |  |  |     assert postJsonObject['object']['replies'] == {} | 
					
						
							|  |  |  |  |     assert postJsonObject['object']['shares'] == {} | 
					
						
							|  |  |  |  |     assert postJsonObject['object']['bookmarks'] == {} | 
					
						
							|  |  |  |  |     assert postJsonObject['object']['ignores'] == {} | 
					
						
							|  |  |  |  |     assert not removePostInteractions(postJsonObject, False) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  | def testSpoofGeolocation() -> None: | 
					
						
							|  |  |  |  |     print('testSpoofGeolocation') | 
					
						
							|  |  |  |  |     citiesList = [ | 
					
						
							| 
									
										
										
										
											2021-05-18 16:58:44 +00:00
										 |  |  |  |         'NEW YORK, USA:40.7127281:W74.0060152:784', | 
					
						
							|  |  |  |  |         'LOS ANGELES, USA:34.0536909:W118.242766:1214', | 
					
						
							|  |  |  |  |         'HOUSTON, USA:29.6072:W95.1586:1553', | 
					
						
							|  |  |  |  |         'MANCHESTER, ENGLAND:53.4794892:W2.2451148:630', | 
					
						
							| 
									
										
										
										
											2021-05-18 17:46:40 +00:00
										 |  |  |  |         'BERLIN, GERMANY:52.5170365:13.3888599:891', | 
					
						
							|  |  |  |  |         'ANKARA, TURKEY:39.93:32.85:24521' | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     ] | 
					
						
							|  |  |  |  |     currTime = datetime.datetime.utcnow() | 
					
						
							| 
									
										
										
										
											2021-05-10 13:43:38 +00:00
										 |  |  |  |     decoySeed = 7634681 | 
					
						
							| 
									
										
										
										
											2021-05-10 10:46:45 +00:00
										 |  |  |  |     cityRadius = 0.1 | 
					
						
							|  |  |  |  |     coords = spoofGeolocation('', 'los angeles', currTime, | 
					
						
							| 
									
										
										
										
											2021-05-10 11:19:42 +00:00
										 |  |  |  |                               decoySeed, citiesList) | 
					
						
							| 
									
										
										
										
											2021-05-18 16:58:44 +00:00
										 |  |  |  |     assert coords[0] >= 34.0536909 - cityRadius | 
					
						
							|  |  |  |  |     assert coords[0] <= 34.0536909 + cityRadius | 
					
						
							|  |  |  |  |     assert coords[1] >= 118.242766 - cityRadius | 
					
						
							|  |  |  |  |     assert coords[1] <= 118.242766 + cityRadius | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     assert coords[2] == 'N' | 
					
						
							|  |  |  |  |     assert coords[3] == 'W' | 
					
						
							| 
									
										
										
										
											2021-05-11 12:36:35 +00:00
										 |  |  |  |     assert len(coords[4]) > 4 | 
					
						
							|  |  |  |  |     assert len(coords[5]) > 4 | 
					
						
							|  |  |  |  |     assert coords[6] > 0 | 
					
						
							| 
									
										
										
										
											2021-05-10 10:46:45 +00:00
										 |  |  |  |     coords = spoofGeolocation('', 'unknown', currTime, | 
					
						
							| 
									
										
										
										
											2021-05-10 11:19:42 +00:00
										 |  |  |  |                               decoySeed, citiesList) | 
					
						
							| 
									
										
										
										
											2021-05-10 10:46:45 +00:00
										 |  |  |  |     assert coords[0] >= 51.8744 - cityRadius | 
					
						
							|  |  |  |  |     assert coords[0] <= 51.8744 + cityRadius | 
					
						
							|  |  |  |  |     assert coords[1] >= 0.368333 - cityRadius | 
					
						
							|  |  |  |  |     assert coords[1] <= 0.368333 + cityRadius | 
					
						
							| 
									
										
										
										
											2021-05-09 19:29:53 +00:00
										 |  |  |  |     assert coords[2] == 'N' | 
					
						
							|  |  |  |  |     assert coords[3] == 'W' | 
					
						
							| 
									
										
										
										
											2021-05-11 12:36:35 +00:00
										 |  |  |  |     assert len(coords[4]) == 0 | 
					
						
							|  |  |  |  |     assert len(coords[5]) == 0 | 
					
						
							|  |  |  |  |     assert coords[6] == 0 | 
					
						
							| 
									
										
										
										
											2021-05-10 13:43:38 +00:00
										 |  |  |  |     kmlStr = '<?xml version="1.0" encoding="UTF-8"?>\n' | 
					
						
							|  |  |  |  |     kmlStr += '<kml xmlns="http://www.opengis.net/kml/2.2">\n' | 
					
						
							|  |  |  |  |     kmlStr += '<Document>\n' | 
					
						
							|  |  |  |  |     for i in range(1000): | 
					
						
							|  |  |  |  |         dayNumber = randint(10, 30) | 
					
						
							|  |  |  |  |         hour = randint(1, 23) | 
					
						
							|  |  |  |  |         hourStr = str(hour) | 
					
						
							|  |  |  |  |         if hour < 10: | 
					
						
							|  |  |  |  |             hourStr = '0' + hourStr | 
					
						
							|  |  |  |  |         currTime = datetime.datetime.strptime("2021-05-" + str(dayNumber) + | 
					
						
							|  |  |  |  |                                               " " + hourStr + ":14", | 
					
						
							|  |  |  |  |                                               "%Y-%m-%d %H:%M") | 
					
						
							| 
									
										
										
										
											2021-05-18 16:58:44 +00:00
										 |  |  |  |         coords = spoofGeolocation('', 'new york, usa', currTime, | 
					
						
							| 
									
										
										
										
											2021-05-10 13:43:38 +00:00
										 |  |  |  |                                   decoySeed, citiesList) | 
					
						
							| 
									
										
										
										
											2021-05-18 16:58:44 +00:00
										 |  |  |  |         longitude = coords[1] | 
					
						
							|  |  |  |  |         if coords[3] == 'W': | 
					
						
							|  |  |  |  |             longitude = -coords[1] | 
					
						
							| 
									
										
										
										
											2021-05-10 13:43:38 +00:00
										 |  |  |  |         kmlStr += '<Placemark id="' + str(i) + '">\n' | 
					
						
							|  |  |  |  |         kmlStr += '  <name>' + str(i) + '</name>\n' | 
					
						
							|  |  |  |  |         kmlStr += '  <Point>\n' | 
					
						
							| 
									
										
										
										
											2021-05-18 16:58:44 +00:00
										 |  |  |  |         kmlStr += '    <coordinates>' + str(longitude) + ',' + \ | 
					
						
							| 
									
										
										
										
											2021-05-10 13:43:38 +00:00
										 |  |  |  |             str(coords[0]) + ',0</coordinates>\n' | 
					
						
							|  |  |  |  |         kmlStr += '  </Point>\n' | 
					
						
							|  |  |  |  |         kmlStr += '</Placemark>\n' | 
					
						
							|  |  |  |  |     kmlStr += '</Document>\n' | 
					
						
							|  |  |  |  |     kmlStr += '</kml>' | 
					
						
							|  |  |  |  |     kmlFile = open('unittest_decoy.kml', 'w+') | 
					
						
							|  |  |  |  |     if kmlFile: | 
					
						
							|  |  |  |  |         kmlFile.write(kmlStr) | 
					
						
							|  |  |  |  |         kmlFile.close() | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 14:13:27 +00:00
										 |  |  |  | def testSkills() -> None: | 
					
						
							|  |  |  |  |     print('testSkills') | 
					
						
							|  |  |  |  |     actorJson = { | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  |         'hasOccupation': [ | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 '@type': 'Occupation', | 
					
						
							|  |  |  |  |                 'name': "Sysop", | 
					
						
							| 
									
										
										
										
											2021-05-17 10:27:14 +00:00
										 |  |  |  |                 "occupationLocation": { | 
					
						
							|  |  |  |  |                     "@type": "City", | 
					
						
							|  |  |  |  |                     "name": "Fediverse" | 
					
						
							| 
									
										
										
										
											2021-05-17 09:12:10 +00:00
										 |  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  |                 'skills': [] | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2021-05-13 14:13:27 +00:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     skillsDict = { | 
					
						
							|  |  |  |  |         'bakery': 40, | 
					
						
							|  |  |  |  |         'gardening': 70 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     setSkillsFromDict(actorJson, skillsDict) | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  |     assert actorHasSkill(actorJson, 'bakery') | 
					
						
							|  |  |  |  |     assert actorHasSkill(actorJson, 'gardening') | 
					
						
							|  |  |  |  |     assert actorSkillValue(actorJson, 'bakery') == 40 | 
					
						
							|  |  |  |  |     assert actorSkillValue(actorJson, 'gardening') == 70 | 
					
						
							| 
									
										
										
										
											2021-05-13 14:13:27 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 19:58:16 +00:00
										 |  |  |  | def testRoles() -> None: | 
					
						
							|  |  |  |  |     print('testRoles') | 
					
						
							|  |  |  |  |     actorJson = { | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  |         'hasOccupation': [ | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 '@type': 'Occupation', | 
					
						
							|  |  |  |  |                 'name': "Sysop", | 
					
						
							| 
									
										
										
										
											2021-05-17 10:27:14 +00:00
										 |  |  |  |                 'occupationLocation': { | 
					
						
							|  |  |  |  |                     '@type': 'City', | 
					
						
							|  |  |  |  |                     'name': 'Fediverse' | 
					
						
							| 
									
										
										
										
											2021-05-17 09:12:10 +00:00
										 |  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  |                 'skills': [] | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2021-05-13 19:58:16 +00:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     testRolesList = ["admin", "moderator"] | 
					
						
							|  |  |  |  |     setRolesFromList(actorJson, testRolesList) | 
					
						
							| 
									
										
										
										
											2021-05-16 15:10:39 +00:00
										 |  |  |  |     assert actorHasRole(actorJson, "admin") | 
					
						
							|  |  |  |  |     assert actorHasRole(actorJson, "moderator") | 
					
						
							|  |  |  |  |     assert not actorHasRole(actorJson, "editor") | 
					
						
							|  |  |  |  |     assert not actorHasRole(actorJson, "counselor") | 
					
						
							| 
									
										
										
										
											2021-05-17 16:13:56 +00:00
										 |  |  |  |     assert not actorHasRole(actorJson, "artist") | 
					
						
							| 
									
										
										
										
											2021-05-13 19:58:16 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  | def runAllTests(): | 
					
						
							|  |  |  |  |     print('Running tests...') | 
					
						
							| 
									
										
										
										
											2020-12-22 12:59:46 +00:00
										 |  |  |  |     testFunctions() | 
					
						
							| 
									
										
										
										
											2021-05-13 19:58:16 +00:00
										 |  |  |  |     testRoles() | 
					
						
							| 
									
										
										
										
											2021-05-13 14:13:27 +00:00
										 |  |  |  |     testSkills() | 
					
						
							| 
									
										
										
										
											2021-05-09 19:11:05 +00:00
										 |  |  |  |     testSpoofGeolocation() | 
					
						
							| 
									
										
										
										
											2021-04-30 11:45:46 +00:00
										 |  |  |  |     testRemovePostInteractions() | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |  |     testExtractPGPPublicKey() | 
					
						
							| 
									
										
										
										
											2021-03-08 18:47:55 +00:00
										 |  |  |  |     testEmojiImages() | 
					
						
							| 
									
										
										
										
											2021-03-03 20:34:55 +00:00
										 |  |  |  |     testCamelCaseSplit() | 
					
						
							| 
									
										
										
										
											2021-03-01 21:46:44 +00:00
										 |  |  |  |     testSpeakerReplaceLinks() | 
					
						
							| 
									
										
										
										
											2021-03-01 10:02:55 +00:00
										 |  |  |  |     testExtractTextFieldsInPOST() | 
					
						
							| 
									
										
										
										
											2021-02-24 20:37:59 +00:00
										 |  |  |  |     testMarkdownToHtml() | 
					
						
							| 
									
										
										
										
											2021-02-09 13:28:42 +00:00
										 |  |  |  |     testValidHashTag() | 
					
						
							| 
									
										
										
										
											2021-02-02 21:08:33 +00:00
										 |  |  |  |     testPrepareHtmlPostNickname() | 
					
						
							| 
									
										
										
										
											2021-01-25 12:24:40 +00:00
										 |  |  |  |     testDomainHandling() | 
					
						
							| 
									
										
										
										
											2021-01-22 13:32:37 +00:00
										 |  |  |  |     testMastoApi() | 
					
						
							| 
									
										
										
										
											2021-01-02 10:37:19 +00:00
										 |  |  |  |     testLinksWithinPost() | 
					
						
							| 
									
										
										
										
											2020-12-13 19:53:31 +00:00
										 |  |  |  |     testReplyToPublicPost() | 
					
						
							| 
									
										
										
										
											2020-12-13 19:05:26 +00:00
										 |  |  |  |     testGetMentionedPeople() | 
					
						
							| 
									
										
										
										
											2020-12-05 11:11:32 +00:00
										 |  |  |  |     testGuessHashtagCategory() | 
					
						
							| 
									
										
										
										
											2020-11-24 10:53:10 +00:00
										 |  |  |  |     testValidNickname() | 
					
						
							| 
									
										
										
										
											2020-11-22 18:43:01 +00:00
										 |  |  |  |     testParseFeedDate() | 
					
						
							| 
									
										
										
										
											2020-11-08 11:24:43 +00:00
										 |  |  |  |     testFirstParagraphFromString() | 
					
						
							| 
									
										
										
										
											2020-10-25 10:06:54 +00:00
										 |  |  |  |     testGetNewswireTags() | 
					
						
							| 
									
										
										
										
											2020-10-17 12:05:41 +00:00
										 |  |  |  |     testHashtagRuleTree() | 
					
						
							| 
									
										
										
										
											2020-10-11 09:33:31 +00:00
										 |  |  |  |     testRemoveHtmlTag() | 
					
						
							| 
									
										
										
										
											2020-09-14 09:33:42 +00:00
										 |  |  |  |     testReplaceEmailQuote() | 
					
						
							| 
									
										
										
										
											2020-09-03 18:48:32 +00:00
										 |  |  |  |     testConstantTimeStringCheck() | 
					
						
							| 
									
										
										
										
											2020-08-26 18:21:57 +00:00
										 |  |  |  |     testTranslations() | 
					
						
							| 
									
										
										
										
											2020-08-25 19:35:55 +00:00
										 |  |  |  |     testValidContentWarning() | 
					
						
							| 
									
										
										
										
											2020-08-23 11:13:35 +00:00
										 |  |  |  |     testRemoveIdEnding() | 
					
						
							| 
									
										
										
										
											2020-08-21 18:32:16 +00:00
										 |  |  |  |     testJsonPostAllowsComments() | 
					
						
							| 
									
										
										
										
											2020-08-02 17:01:12 +00:00
										 |  |  |  |     runHtmlReplaceQuoteMarks() | 
					
						
							| 
									
										
										
										
											2020-12-13 14:48:45 +00:00
										 |  |  |  |     testDangerousCSS() | 
					
						
							| 
									
										
										
										
											2020-07-10 14:15:01 +00:00
										 |  |  |  |     testDangerousMarkup() | 
					
						
							| 
									
										
										
										
											2020-07-07 14:18:02 +00:00
										 |  |  |  |     testRemoveHtml() | 
					
						
							| 
									
										
										
										
											2020-06-22 16:55:19 +00:00
										 |  |  |  |     testSiteIsActive() | 
					
						
							| 
									
										
										
										
											2020-06-15 12:37:53 +00:00
										 |  |  |  |     testJsonld() | 
					
						
							| 
									
										
										
										
											2020-06-14 13:25:38 +00:00
										 |  |  |  |     testRemoveTextFormatting() | 
					
						
							| 
									
										
										
										
											2020-01-24 11:27:12 +00:00
										 |  |  |  |     testWebLinks() | 
					
						
							| 
									
										
										
										
											2019-11-24 11:28:58 +00:00
										 |  |  |  |     testRecentPostsCache() | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |  |     testTheme() | 
					
						
							| 
									
										
										
										
											2019-11-23 10:13:57 +00:00
										 |  |  |  |     testSaveLoadJson() | 
					
						
							| 
									
										
										
										
											2020-10-11 12:41:15 +00:00
										 |  |  |  |     testJsonString() | 
					
						
							| 
									
										
										
										
											2019-10-12 12:45:53 +00:00
										 |  |  |  |     testGetStatusNumber() | 
					
						
							| 
									
										
										
										
											2020-02-21 15:09:31 +00:00
										 |  |  |  |     testAddEmoji() | 
					
						
							| 
									
										
										
										
											2019-08-21 16:35:46 +00:00
										 |  |  |  |     testActorParsing() | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     testHttpsig() | 
					
						
							| 
									
										
										
										
											2021-02-22 14:03:24 +00:00
										 |  |  |  |     testHttpSigNew() | 
					
						
							| 
									
										
										
										
											2019-06-30 21:20:02 +00:00
										 |  |  |  |     testCache() | 
					
						
							|  |  |  |  |     testThreads() | 
					
						
							| 
									
										
										
										
											2019-07-03 10:04:23 +00:00
										 |  |  |  |     testCreatePerson() | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  |  |     testAuthentication() | 
					
						
							| 
									
										
										
										
											2019-07-05 12:35:29 +00:00
										 |  |  |  |     testFollowersOfPerson() | 
					
						
							| 
									
										
										
										
											2019-07-05 14:25:15 +00:00
										 |  |  |  |     testNoOfFollowersOnDomain() | 
					
						
							| 
									
										
										
										
											2019-07-08 08:51:33 +00:00
										 |  |  |  |     testFollows() | 
					
						
							|  |  |  |  |     testGroupFollowers() | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     print('Tests succeeded\n') |