Package: rikihistory
#Page History FeatureImplementer:
John BessePython: >=3.7#ProblemThere was no way to see a record of changes made to a page in Riki system#SolutionA history markdown file is created in parallel to the page markdown file in a content folder (e.g. content\page.md) it
is tracking and stored with other history files in a history folder#RequirementA user would like a history page in order to see a record of changes made to a Riki page.#Usage Example 1Input:	record_history(r'content\fakepageurl.md', 'action', 'Claude')
Output:	'content/history\\fakepageurl_hist.md'
Text appended to content\history\fakepageurl_hist.md: â€˜action by Claude Sat May 2 18:53:32 2020â€™#Usage Example 2Input:	histurl('wiki-page')
Output:	'history/wiki-page_hist'#Usage Example 3Navigate to directory with rkhist.py
Command Line Input: python rkhist.py -e content\fakepageurl.md moved Ted
Output: none
Text appended to content\history\fakepageurl_hist.md: â€˜moved by Ted Sun May 10 10:56:30 2020â€™#User Manual#In Riki sysem1. Call record_history() in any Riki Flask route with path of page object, desired action description, and user ID.
2. A history page markdown file is created with provided information in content\history subfolder.#Command lineRun rkhist.py in its directory with -e or --entry option and 3 arguments to make a history file
    1. path: file name of page markdown file in content directory (ex: content\fakepageurl.md)
    2. action: a descripton of action performed on page (ex: edited)
    3. user: user name or ID (ex: Ted)#Implementation GoalTo create a module that when a page is edited or moved an entry composed of the action performed and the userâ€™s name is
written to a history markdown file via a file path derived from a Page object.#Implementation DetailsA public function was chosen to implement this feature so that it could be included into any Flask route API with one
line of code in the Riki system. Markdown files with Page object formatting are used to allow history information to
be processed with the same tools that process the wiki pages. An example is this featureâ€™s Jinja template, which is
composed of only the URL and page parameters in two blocks. These files are also kept in a separate history folder
to segregate them from the page files if they need to be processed differently.A history entry is created in a markdown file by record_history(). A new file is created if there is not one present,
and record_history() returns this fileâ€™s path for testing purposes. It creates the files with the same methods as
the wiki.core.Page.save() method in Riki, so no additional modules are needed except Python time module for the time
and date stamp. To complete an entry, the action and user name are concatenated with a time and written to the
markdown file. In this implementation, these calls are made in an actionâ€™s Flask route function to synchronize them
with the actionâ€™s API call.The required parameters are a markdown fileâ€™s path, an action name string, and a user name string. They are as
abstract as possible to allow for flexibility implementing history entries. They could be generated by any function
that returns a string. In Riki, the user name is generated by current_user.get_id(). The path parameter from a Page
object get method also allows any information in the Page to be transcribed into the history file if necessary. The
history markdown file is in Page object format, so they can be easily displayed through a Flask API and Jinja
template.The record_history() and histurl() functions form the basis of creating history pages. Any function that wishes to
create a history entry only needs one line of code to call record_history(). This keeps the overall lines of code low
and reduces complexity. Some Riki operations that modify pages need to be performed on the history page as well to
maintain coherency, such as move or delete. In these cases, the respective method call is performed with the page
URL modified by histurl() to also update the history page.#Modules#1. Files:#rikihistory\history.pycontains histurl and record_history methods and doctests#rikihistory\rkhist.pycommand line script that creates history entry with command line parameters#rikihistory\tests\test_history.pyUnit tests to implement the test plan#rikihistory\README.mdREADME file#history_pydoc.htmlPydoc file#2. Methods:#rikihistory.histurl(url: string): stringThis creates and returns the history file name using its associated pageâ€™s file name. This was a frequent operation
and reduced complexity using a function.#rikihistory.record_history(path: string, action: string, user: string): stringThis function creates or appends a history page markdown file from a Riki page mardown file located in the â€˜contentâ€™
folder and whose path is the path parameter. Files are kept in a separate â€˜historyâ€™ subfolder in the â€˜contentâ€™ 
folder also derived from the path parameter. It formats new history markdown files to be compatible with all Page 
object operations in the Riki system and initiates it with a â€˜Createdâ€™ entry with user parameter and time from 
Python time module. All other history entries are concatenated strings composed of the action and user from 
parameters and the time. It returns the path of the markdown file modified.#3. Tests#test_givenRandUserName_whenHistoryRecordMade_thenUserNameInNewEntry (test 1):With an edit made to the page, a new entry will have the name of the editing user.

Specify a variable to store the user who edits the page.
Compare the user name added to the history entry.

A unit test was created in tests\test_history.py (lines 24-30). Mock was used to create a mock Page object with a
path to a page in the content folder (lines 6-8). A unique user name was created by appending a random integer 
0-1000 (lines 10, 25). A history was recorded with this information (line 26). The history file written to was read
(lines 27-29). If the unique user was in the file (line 30), then a new record was recorded with the user parameter.#test_givenMockPage_whenHistoryRecordMade_thenHistFilePathReturned (test 2):With a history record made for a page, it will modify a history file with a file name derived from its associate 
page in the correct directory location.

1. Specify a variable to store the expected path with directory and file name.
2. Compare the path returned by the record_history() function to the expected path.

A unit test was created in tests\test_history.py (lines 41-44). Mock was used to create a mock Page object with a 
specified path (line 43) to a page in the content folder (lines 6-8). A history record was made using the mocked 
Page and two meaningless string parameters (line 42). If the specified path and the path returned by 
record_history() are equal (line 44), then the file name and directory are correct because this path is used in the
function to make the file (wiki\core.py line 95-96).#test_givenRandAction_whenAddingRecordToExistingHistoryFile_thenActionInNewEntry (test 3):Same as Test 2 but checking if the action name was used instead of user name.

A unit test was created in Test\test_history.py (lines 32-39). It is the same as Test 2 but a random action name was
used (line 33).#test_givenWikiPageURL_thenReturnHistWikiPageURL (test 4):With a page url, it will modify it and return the url of the pageâ€™s associated history file.

1. Specify a variable to store the expected history page url.
2. Compare it to the url returned by histurl().

A unit test was created in Test\test_history.py (lines 19-22). It checks if the string generate by histurl() matches
the expected string.#4. Lines of Code54