mirror of
https://git.code.sf.net/p/seeddms/code
synced 2024-11-26 15:32:13 +00:00
Merge branch 'seeddms-5.1.x' into seeddms-6.0.x
This commit is contained in:
commit
3d880be30c
639
SeedDMS_Core/CHANGELOG.md
Normal file
639
SeedDMS_Core/CHANGELOG.md
Normal file
|
@ -0,0 +1,639 @@
|
|||
5.1.29 (2022-11-21)
|
||||
---------------------
|
||||
- SeedDMS_Core_Folder::addDocument() does rollback transaction propperly when setting document categories fail
|
||||
- add $skiproot and $sep parameter to SeedDMS_Core_Folder::getFolderPathPlain()
|
||||
- add class name for 'documentfile'
|
||||
- add method SeedDMS_Core_KeywordCategory::countKeywordLists()
|
||||
|
||||
5.1.28 (2022-11-07)
|
||||
---------------------
|
||||
- fix SeedDMS_Core_User::getDocumentContents()
|
||||
- fix SeedDMS_Core_File::fileExtension()
|
||||
- SeedDMS_Core_DMS::createPasswordRequest() creates a cryptographically secure hash
|
||||
- fix sql error when deleting a folder attribute
|
||||
- add SeedDMS_Core_Attribute::getParsedValue() and use it in SeedDMS_Core_Object::getAttributeValue()
|
||||
- add SeedDMS_Core_DMS::getDuplicateSequenceNo() and SeedDMS_Core_Folder::reorderDocuments()
|
||||
- add SeedDMS_Core_File::mimetype(), fix SeedDMS_Core_File::moveDir()
|
||||
- all file operations use methods of SeedDMS_Core_File
|
||||
- change namespace of iterators from SeedDMS to SeedDMS\Core
|
||||
|
||||
|
||||
5.1.27 (2022-08-31)
|
||||
---------------------
|
||||
- fix SeedDMS_Core_DMS::addAttributeDefinition() when objtype is 0
|
||||
- sort search result even if sortorder is 'i' or 'n'
|
||||
- pass an array as an attribute to search() will OR each element
|
||||
|
||||
5.1.26 (2022-05-20)
|
||||
---------------------
|
||||
- fix validating multi value attributes
|
||||
- SeedDMS_Core_User::removeFromProcesses() can be limited to a list of documents. In that case only the last version will be modified.
|
||||
- add more types to getStatisticalData()
|
||||
- add optional parameter $op to SeedDMS_Core_AttributeDefinition::getObjects()
|
||||
- SeedDMS_Core_AttributeDefinition::getObjects() will not filter by value if null is passed
|
||||
- SeedDMS_Core_DMS::getAllAttributeDefinitions() has second parameter to filter attributes by type
|
||||
|
||||
5.1.25 (2022-04-22)
|
||||
---------------------
|
||||
- rename getLastWorkflowTransition() to getLastWorkflowLog()
|
||||
- getLastWorkflowLog() returns a workflow entry even if the workflow has ended
|
||||
- backport setFileType() from 6.0.x
|
||||
- add SeedDMS_Core_File::fileExtension()
|
||||
- add callbacks on onPostUpdateAttribute, onPostRemoveAttribute, onPostAddAttribute
|
||||
- fix searching for document content with a custom attribute having a value set
|
||||
|
||||
5.1.24 (2021-12-11)
|
||||
---------------------
|
||||
- in SeedDMS_Core_DocumentContent::removeWorkflow() remove records from tblWorklflowLog before tblDWorkflowDocumentContent
|
||||
- make all class variables of SeedDMS_Core_User protected
|
||||
- fix various errors in SeedDMS_Core_AttributeDefinition::validate()
|
||||
- add lots of unit tests
|
||||
- replace incorrect use of array_search() by in_array()
|
||||
- move method SeedDMS_Core_DMS::createDump() into SeedDMS_Core_DatabaseAccess
|
||||
- lots of parameter checking when calling methods()
|
||||
- make sure callbacks are callable
|
||||
- SeedDMS_Core_Folder::getParent() returns null if there is no parent (used to be false)
|
||||
- SeedDMS_Core_DMS::search() will not find document without an expiration date anymore, if the search is limited by an expiration end date but no start date
|
||||
- add method SeedDMS_Core_Folder::getFoldersMinMax()
|
||||
- init internal cache variables of SeedDMS_Core_Folder/SeedDMS_Core_Document and add method clearCache()
|
||||
- SeedDMS_Core_Folder::hasDocuments() does not use the interal document cache anymore
|
||||
- SeedDMS_Core_Document::addDocumentLink() returns an object of type SeedDMS_Core_DocumentLink in case of success
|
||||
- trim email, comment, language, theme when setting data of user
|
||||
- more checks whether an id > 0 when getting a database record
|
||||
|
||||
5.1.23 (2021-08-19)
|
||||
---------------------
|
||||
- SeedDMS_Core_DMS::getTimeline() uses status log instead of document content
|
||||
- add methods SeedDMS_Core_DocumentContent::getReviewers() and SeedDMS_Core_DocumentContent::getApprovers()
|
||||
- add methods SeedDMS_Core_DocumentContent::getApproveLog() and SeedDMS_Core_DocumentContent::getReviewLog()
|
||||
- better handling of document with an empty workflow state
|
||||
- fix checking of email addresses by using filter_var instead of regex
|
||||
- add new method SeedDMS_Core_Document::hasCategory()
|
||||
- add new method SeedDMS_Core_DocumentContent::removeReview()
|
||||
- add new method SeedDMS_Core_DocumentContent::removeApproval()
|
||||
- add new method SeedDMS_Core_User::getFolders()
|
||||
- add new method SeedDMS_Core_User::getDocumentContents()
|
||||
- add new method SeedDMS_Core_User::getDocumentFiles()
|
||||
- add new method SeedDMS_Core_User::getDocumentLinks()
|
||||
- add new type 'foldersperuser' to method SeedDMS_Core_DMS::getStatisticalData()
|
||||
|
||||
5.1.22 (2021-03-15)
|
||||
---------------------
|
||||
- add SeedDMS_Core_DatabaseAccess::hasTable()
|
||||
- add SeedDMS_Core_User->isType() and SeedDMS_Core_Group->isType()
|
||||
- add SeedDMS_Core_User->getDMS() and SeedDMS_Core_Group->getDMS()
|
||||
- add new parameter to SeedDMS_Core_DMS->getDocumentList() for skipping expired documents
|
||||
- add parameter $incdisabled to SeedDMS_Core_Folder::getNotifyList()
|
||||
- do not validate value in SeedDMS_Core_Attribute::setValue(), it should have been done before
|
||||
- SeedDMS_Core_DMS::search() can search for last date of document status change
|
||||
- smarter caching in SeedDMS_Core_Document::getDocumentFiles() which fixes a potential
|
||||
problem when removing a document
|
||||
|
||||
5.1.21 (2020-09-29)
|
||||
---------------------
|
||||
- SeedDMS_Folder_DMS::getAccessList() and getDefaultAccess() do not return fals anymore if the parent does not exists. They just stop inheritance.
|
||||
- pass attribute value to callback 'onAttributeValidate'
|
||||
- new paramter 'new' of methode SeedDMЅ_Core_AttributeDefinition::validate()
|
||||
- check if folder/document is below rootDir can be turned on (default off)
|
||||
- SeedDMS_Core_User::setHomeFolder() can be used to unset the home folder
|
||||
- check if attribute definition exists when setting attributes of folders and documents
|
||||
|
||||
5.1.20 (2020-09-29)
|
||||
---------------------
|
||||
- SeedDMS_Core_DMS::getDocumentList() returns false, if an unknown list is passed
|
||||
- SeedDMS_Core_Document::getDocumentFiles() has new parameter to select only those files attached to a specific version of the document
|
||||
- removing a document version will not remove attachments of the document anymore
|
||||
- set dms of new user instances in SeedDMS_Core_Group
|
||||
|
||||
5.1.19 (2020-07-30)
|
||||
---------------------
|
||||
- add method SeedDMS_Core_Document::setParent() as an alias for setFolder()
|
||||
- clear the save content list and latest content in SeedDMS_Core_Document after
|
||||
a version has been deleted.
|
||||
- new method SeedDMS_Core_Document::isLatestVersion()
|
||||
- add new attribute types 'document', 'folder', 'user', 'group'
|
||||
|
||||
5.1.18 (2020-05-28)
|
||||
---------------------
|
||||
- fixed remaining todos
|
||||
- fixed parsing of file size in SeedDMS_Core_File::parse_filesize()
|
||||
- fix SeedDMS_Core_DMS::getDocumentByOriginalFilename()
|
||||
|
||||
5.1.17 (2020-05-22)
|
||||
---------------------
|
||||
- add new callback onSetStatus
|
||||
- fix SeedDMS_Core_DMS::getExpiredDocuments(), sql statement failed because temp. tables were not created
|
||||
- add parameters $orderdir, $orderby, $update to SeedDMS_Core::getExpiredDocuments()
|
||||
|
||||
5.1.16 (2020-04-14)
|
||||
---------------------
|
||||
- fix call of hooks in SeedDMS_Core
|
||||
- add variable lasterror in SeedDMS_Core_DMS which can be set by hooks to pass an
|
||||
error msg to the calling application
|
||||
- better error checking in SeedDMS_Core_Document::addDocumentFile()
|
||||
|
||||
5.1.15 (2020-03-02)
|
||||
---------------------
|
||||
- no changes, just keep same version as seeddms application
|
||||
|
||||
5.1.14 (2020-02-17)
|
||||
---------------------
|
||||
- speed up SeedDMS_Core_Folder::getSubFolders() SeedDMS_Core_Folder::getDocuments() by minimizing the number of sql queries.
|
||||
|
||||
5.1.13 (2019-09-06)
|
||||
---------------------
|
||||
- add decorators
|
||||
- add new methods SeedDMS_Core_Document::isType(), SeedDMS_Core_Folder::isType(), SeedDMS_Core_DocumentContent::isType(). Use them instead of checking the class name.
|
||||
- skip a fileType with just a '.'
|
||||
|
||||
5.1.12 (2019-07-01)
|
||||
---------------------
|
||||
- parameter $orderby passed to SeedDMS_Core_Folder::getDocuments() and SeedDMS_Core_Folder::getSubFolders() can be a string, but only the first char is evaluated
|
||||
- SeedDMS_Core_DMS::search() excepts parameters as array, added orderby
|
||||
- add SeedDMS_Core_Folder::hasSubFolderByName()
|
||||
- fix SeedDMS_Core_Folder::hasDocumentByName() which returned an int > 0 if documents
|
||||
has been loaded before and even if the document searching for was not among them.
|
||||
- add new method SeedDMS_Core_Folder::empty()
|
||||
|
||||
5.1.11 (2019-05-03)
|
||||
---------------------
|
||||
- ???
|
||||
|
||||
5.1.10 (2019-04-04)
|
||||
---------------------
|
||||
- fix php warning if workflow state doesn' have next transition
|
||||
- add method SeedDMS_Core_DatabaseAccess::setLogFp()
|
||||
|
||||
5.1.9 (2018-11-13)
|
||||
---------------------
|
||||
- context can be passed to getAccessMode()
|
||||
- call hook in SeedDMS_Core_Folder::getAccessMode()
|
||||
- new optional parameter $listguest for SeedDMS_Core_Document::getReadAccessList()
|
||||
- remove deprecated methods SeedDMS_Core_Document::convert(), SeedDMS_Core_Document::wasConverted(), SeedDMS_Core_Document::viewOnline(), SeedDMS_Core_Document::getUrl()
|
||||
|
||||
5.1.8 (2018-07-02)
|
||||
---------------------
|
||||
- SeedDMS_Core_DMS::search() returns false in case of an error
|
||||
- do not use views in DBAccessPDO by default anymore, use temp. tables
|
||||
- SeedDMS_Core_Document::getNotifyList() has new parameter to include disabled user in list
|
||||
- fix possible sql injection in SeedDMS_Core_User
|
||||
|
||||
5.1.7 (2018-04-05)
|
||||
---------------------
|
||||
- just bump version
|
||||
|
||||
5.1.6 (2018-02-14)
|
||||
---------------------
|
||||
- add SeedDMS_Core_Folder::getDocumentsMinMax()
|
||||
- add lots of DocBlocks from merge request #8
|
||||
- add SeedDMS_Core_AttributeDefinition::removeValue()
|
||||
|
||||
5.1.5 (2017-11-07)
|
||||
---------------------
|
||||
- use views instead of temp. tables
|
||||
- add list of expired documents in SeedDMS_Core_DMS::getDocumentList()
|
||||
- add methods to set comment, name, public, version of document files
|
||||
- add method SeedDMS_Core_Document::transferToUser()
|
||||
- SeedDMS_Core_Document::addDocumentFile() returns object of file
|
||||
- add SeedDMS_Core_DocumentFile::setDate()
|
||||
- remove SeedDMS_Core_DocumentCategory::addCategory() and getCategories()
|
||||
- add optional parameters $limit and $offset to SeedDMS_Core_Folder::getDocuments()
|
||||
and SeedDMS_Core_Folder::getSubFolders()
|
||||
- getInstance() returns now null instead of false if the object was not found in the db
|
||||
- add new methods SeedDMS_Core_Document::addCategories() and
|
||||
SeedDMS_Core_Document::removeCategories()
|
||||
|
||||
5.1.4 (2017-09-05)
|
||||
---------------------
|
||||
- add virtual access mode for document links and attachments plus callbacks to
|
||||
check access mode in a hook
|
||||
- add new method SeedDMS_Core_DMS::getDocumentsExpired()
|
||||
- all changes from 5.0.14 merged
|
||||
|
||||
5.1.3 (2017-08-23)
|
||||
---------------------
|
||||
- SeedDMS_Core_Document::getNotifyList() and SeedDMS_Core_Folder::getNotifyList()
|
||||
returns just users which are not disabled
|
||||
- add new methods removeFromProcesses(), getWorkflowsInvolved(), getKeywordCategories() to SeedDMS_Core_User
|
||||
- add methods isMandatoryReviewerOf() and isMandatoryApproverOf()
|
||||
- add methods transferDocumentsFolders() and transferEvents()
|
||||
- add method SeedDMS_Core_DMS::getDocumentByOriginalFilename()
|
||||
|
||||
5.1.2 (2017-03-23)
|
||||
---------------------
|
||||
- SeedDMS_Core_DMS::filterDocumentFiles() returns also documents which are not public
|
||||
if the owner tries to access them
|
||||
- Check return value of onPreRemove[Document
|
||||
Folder], return from calling method if bool
|
||||
- Add SeedDMS_Core_DMS::getDocumentList()
|
||||
- Limit number of duplicate files to 1000
|
||||
- Add hook on(Pre
|
||||
Post)RemoveContent
|
||||
- Add hook onAttributeValidate
|
||||
|
||||
5.1.1 (2017-02-20)
|
||||
---------------------
|
||||
- all changes from 5.0.11 merged
|
||||
|
||||
5.1.0 (2017-02-20)
|
||||
---------------------
|
||||
- added postgres support
|
||||
|
||||
5.0.13 (2017-07-13)
|
||||
---------------------
|
||||
- all changes from 4.3.36 merged
|
||||
|
||||
5.0.12 (2017-03-23)
|
||||
---------------------
|
||||
all sql statements can be logged to a file
|
||||
do not sort some temporary tables anymore, because it causes an error in mysql if sql_mode=only_full_group_by is set
|
||||
|
||||
5.0.11 (2017-02-28)
|
||||
---------------------
|
||||
- all changes from 4.3.34 merged
|
||||
|
||||
5.0.10 (2017-02-20)
|
||||
---------------------
|
||||
- all changes from 4.3.33 merged
|
||||
|
||||
5.0.9 (2016-11-02)
|
||||
---------------------
|
||||
- all changes from 4.3.32 merged
|
||||
|
||||
5.0.8 (2016-11-02)
|
||||
---------------------
|
||||
- all changes from 4.3.31 merged
|
||||
|
||||
5.0.7 (2016-11-02)
|
||||
---------------------
|
||||
- all changes from 4.3.30 merged
|
||||
- better attribute value checking
|
||||
|
||||
5.0.6 (2016-09-06)
|
||||
---------------------
|
||||
- all changes from 4.3.29 merged
|
||||
|
||||
5.0.5 (2016-08-09)
|
||||
---------------------
|
||||
- all changes from 4.3.28 merged
|
||||
|
||||
5.0.4 (2016-05-03)
|
||||
---------------------
|
||||
- all changes from 4.3.27 merged
|
||||
|
||||
5.0.3 (2016-04-04)
|
||||
---------------------
|
||||
- use classname from SeedDMS_Core_DMS::_classnames for SeedDMS_Core_DocumentContent
|
||||
- all changes from 4.3.26 merged
|
||||
|
||||
5.0.2 (2016-04-26)
|
||||
---------------------
|
||||
- all changes from 4.3.25 merged
|
||||
|
||||
5.0.1 (2016-01-22)
|
||||
---------------------
|
||||
- all changes from 4.3.24 merged
|
||||
|
||||
5.0.0 (2016-01-22)
|
||||
---------------------
|
||||
- classes can be overloaded
|
||||
- clean workflow log when a document version was deleted
|
||||
|
||||
4.3.37 (2018-02-14)
|
||||
---------------------
|
||||
- SeedDMS_Core_DMS::search() finds documents without a status log
|
||||
|
||||
4.3.36 (2017-03-22)
|
||||
---------------------
|
||||
- fix sql statement for creating temp. tables (sqlite)
|
||||
|
||||
4.3.35 (2017-07-11)
|
||||
---------------------
|
||||
do not sort some temporary tables anymore, because it causes an error in mysql if sql_mode=only_full_group_by is set
|
||||
|
||||
4.3.34 (2017-02-28)
|
||||
---------------------
|
||||
SeedDMS_Core_DMS::getDuplicateDocumentContent() returns complete document
|
||||
|
||||
4.3.33 (2017-02-22)
|
||||
---------------------
|
||||
- SeedDMЅ_Core_DMS::getTimeline() no longer returns duplicate documents
|
||||
- SeedDMЅ_Core_Document::addContent() sets workflow after status was set
|
||||
- SeedDMЅ_Core_Keyword::setOwner() fix sql statement
|
||||
- SeedDMЅ_Core_User::setFullname() minor fix in sql statement
|
||||
|
||||
4.3.32 (2017-01-12)
|
||||
---------------------
|
||||
- order groups by name returned by getReadAccessList()
|
||||
- add optional parameter to SeedDMS_Core_DMS::filterDocumentLinks()
|
||||
- SeedDMS_Core_DMS::search() can search for document/folder id
|
||||
|
||||
4.3.31 (2016-11-02)
|
||||
---------------------
|
||||
- new method SeedDMЅ_Core_WorkflowAction::getTransitions()
|
||||
- new method SeedDMЅ_Core_WorkflowState::getTransitions()
|
||||
- new method SeedDMЅ_Core_AttributeDefinition::parseValue()
|
||||
- add check for cycles in workflow SeedDMS_Core_Workflow::checkForCycles()
|
||||
|
||||
4.3.30 (2016-10-07)
|
||||
---------------------
|
||||
- new method SeedDMЅ_Core_AttributeDefinition::getValueSetSeparator()
|
||||
- trim each value of a value set before saving the complete value set as a string
|
||||
|
||||
4.3.29 (2016-09-06)
|
||||
---------------------
|
||||
- SeedDMЅ_Core_Object::getAttributes() orders attributes by name of attribute definition
|
||||
- SeedDMЅ_Core_Workflow::addTransition() force reload of transition list after adding a
|
||||
- SeedDMЅ_Core_Document::rewrite[Review
|
||||
Approval]Log() will also copy file if it exists
|
||||
- add method SeedDMЅ_Core_Document::rewriteWorkflowLog()
|
||||
|
||||
4.3.28 (2016-08-24)
|
||||
---------------------
|
||||
- SeedDMЅ_Core_DMS::search() searches also comment of document version
|
||||
|
||||
4.3.27 (2016-04-26)
|
||||
---------------------
|
||||
- callbacks can have more then one user function
|
||||
- fix some sql statements, because they didn't work with mysql 5.7.5 anymore
|
||||
|
||||
4.3.26 (2016-04-04)
|
||||
---------------------
|
||||
- add more callbacks
|
||||
|
||||
4.3.25 (2016-03-08)
|
||||
---------------------
|
||||
- rename SeedDMS_Core_Group::getNotificationsByGroup() to getNotifications()
|
||||
- use __construct() for all constructors
|
||||
- fix setting multi value attributes for versions
|
||||
|
||||
4.3.24 (2016-01-22)
|
||||
---------------------
|
||||
- make sure boolean attribute is saved as 0/1
|
||||
- add SeedDMS_Core_User::[g
|
||||
s]etMandatoryWorkflows()
|
||||
- add SeedDMS_Core_User::getNotifications()
|
||||
- add SeedDMS_Core_Group::getNotifications()
|
||||
- SeedDMS_Core_DMS::getNotificationsByGroup() and
|
||||
SeedDMS_Core_DMS::getNotificationsByUser() are deprecated
|
||||
- SeedDMS_Core_DocumentCategory::getDocumentsByCategory() now returns the documents
|
||||
- add SeedDMS_Core_Group::getWorkflowStatus()
|
||||
- SeedDMS_Core_User::getDocumentsLocked() sets locking user propperly
|
||||
|
||||
4.3.24 (2016-01-21)
|
||||
---------------------
|
||||
- make sure boolean attribute is saved as 0/1
|
||||
- add SeedDMS_Core_User::[g
|
||||
s]etMandatoryWorkflows()
|
||||
- add SeedDMS_Core_User::getNotifications()
|
||||
- add SeedDMS_Core_Group::getNotifications()
|
||||
- SeedDMS_Core_DMS::getNotificationsByGroup() and
|
||||
SeedDMS_Core_DMS::getNotificationsByUser() are deprecated
|
||||
- SeedDMS_Core_DocumentCategory::getDocumentsByCategory() now returns the documents
|
||||
- add SeedDMS_Core_Group::getWorkflowStatus()
|
||||
- SeedDMS_Core_User::getDocumentsLocked() sets locking user propperly
|
||||
|
||||
4.3.23 (2016-01-21)
|
||||
---------------------
|
||||
- new method SeedDMS_Core_DMS::createDump()
|
||||
- minor improvements int SeedDMS_Core_Document::getReadAccessList()
|
||||
|
||||
4.3.22 (2015-11-09)
|
||||
---------------------
|
||||
- fix sql statement to reset password
|
||||
- pass some more information for timeline
|
||||
|
||||
4.3.21 (2015-09-28)
|
||||
---------------------
|
||||
- add method SeedDMS_Core_Database::getCurrentTimestamp()
|
||||
- add method SeedDMS_Core_Database::getCurrentDatetime()
|
||||
- user getCurrentTimestamp() and getCurrentDatetime() whenever possible
|
||||
|
||||
4.3.20 (2015-06-26)
|
||||
---------------------
|
||||
- add method SeedDMS_Core_DMS::checkDate()
|
||||
- add method SeedDMS_Core_Document::setDate()
|
||||
- add method SeedDMS_Core_Folder::setDate()
|
||||
- date can be passed to SeedDMS_Core_DocumentContent::setStatus()
|
||||
- add method SeedDMS_Core_DocumentContent::rewriteStatusLog()
|
||||
- add method SeedDMS_Core_DocumentContent::rewriteReviewLog()
|
||||
- add method SeedDMS_Core_DocumentContent::rewriteApprovalLog()
|
||||
- access rights for guest are also taken into account if set in an acl. Previously guest could gain read rights even if the access was probibited
|
||||
by a group or user right
|
||||
|
||||
4.3.19 (2015-06-26)
|
||||
---------------------
|
||||
- add optional paramter $noclean to clearAccessList(), setDefaultAccess(), setInheritAccess()
|
||||
- clearAccessList() will clean up the notifier list
|
||||
- new method cleanNotifyList()
|
||||
|
||||
4.3.18 (2015-06-09)
|
||||
---------------------
|
||||
- add optional paramter $msg to SeedDMS_Core_DocumentContent::verifyStatus()
|
||||
- add method SeedDMS_Core_DMS::getDuplicateDocumentContent()
|
||||
|
||||
4.3.17 (2015-03-27)
|
||||
---------------------
|
||||
clean workflow log when a document version was deleted
|
||||
|
||||
4.3.16 (2015-03-20)
|
||||
---------------------
|
||||
no changes
|
||||
|
||||
4.3.15 (2015-02-12)
|
||||
---------------------
|
||||
users returned by SeedDMS_Core_DMS::getAllUsers() have language and theme set again
|
||||
|
||||
4.3.13 (2014-11-27)
|
||||
---------------------
|
||||
- fix searching for attributes
|
||||
- add some more documentation
|
||||
- SeedDMS_Core_DMS::getDocumentCategories() returns categories sorted by name (Bug #181)
|
||||
- new methode SeedDMS_Core_Document::replaceContent() which replaces the content of a version.
|
||||
<release>4.3.14</release>
|
||||
- add missing start transaction in SeedDMD_Core_Folder::remove()
|
||||
- SeedDMD_Core_Folder::isSubFolder() doesn't compare object instances anymore (Bug #194)
|
||||
|
||||
4.3.12 (2014-11-17)
|
||||
---------------------
|
||||
- fix searching folders with multivalue attributes
|
||||
|
||||
4.3.11 (2014-11-13)
|
||||
---------------------
|
||||
- fixed saving multivalue attributes
|
||||
- add method SeedDMS_Core_Attribute::getValueAsArray()
|
||||
|
||||
4.3.10 (2014-10-22)
|
||||
---------------------
|
||||
new release
|
||||
|
||||
4.3.9 (2014-07-30)
|
||||
---------------------
|
||||
- SeedDMS_Core_KeywordCategory::getKeywordLists() sorts keywords aphabetically
|
||||
- SeedDMS_Core_DMS::addUser() doesn't throw an error if sql_mode is set to STRICT_TRANS_TABLES and pwdexpiration is not set to a valid date.
|
||||
|
||||
4.3.8 (2014-04-09)
|
||||
---------------------
|
||||
- new method SeedDMS_Core_DMS::getStatisticalData()
|
||||
|
||||
4.3.7 (2014-03-21)
|
||||
---------------------
|
||||
no changes
|
||||
|
||||
4.3.6 (2014-03-18)
|
||||
---------------------
|
||||
- add optional parameters $publiconly=false and $user=null to SeedDMS_Core_Document::getDocumentLinks()
|
||||
- add new method SeedDMS_Core_Document::getReverseDocumentLinks()
|
||||
|
||||
4.3.5 (2014-03-04)
|
||||
---------------------
|
||||
no changes
|
||||
|
||||
4.3.4 (2014-02-01)
|
||||
---------------------
|
||||
- fix handling of multivalue attributes
|
||||
|
||||
4.3.3 (2014-02-01)
|
||||
---------------------
|
||||
- SeedDMS_Folder::getDocuments() and SeedDMS_Folder::getSubFolders() do not
|
||||
do any sorting if $orderby is not set.
|
||||
- database hostname can have port seperated by ':'
|
||||
- make all functions in SeedDMS_Core_File static (fixes problem with php 5.5.x)
|
||||
|
||||
4.3.2 (2013-11-27)
|
||||
---------------------
|
||||
- new method SeedDMS_Core_Folder::isSubFolder()
|
||||
- check for subFolder in SeedDMS_Core_Folder::setParent()
|
||||
- new methods SeedDMS_Core_DMS::checkFolders() and SeedDMS_Core_DMS::checkDocuments()
|
||||
|
||||
4.3.0 (2013-09-05)
|
||||
---------------------
|
||||
- various small corrections
|
||||
- comment of version is no longer taken from document if version comment is empty
|
||||
- passing an array of users to SeedDMЅ_Core_DMS::search() instead of a single user ist now allowed
|
||||
- turn on foreign key constraints for sqlite3
|
||||
- SeedDMЅ_Core_Folder::getPath() can handle a subfolder treated as a root folder
|
||||
|
||||
4.2.2 (2013-05-17)
|
||||
---------------------
|
||||
- admins can be added as reviewer/approver again
|
||||
|
||||
4.2.1 (2013-04-30)
|
||||
---------------------
|
||||
- fixed bug in SeedDMS_Core_DocumentContent::addIndApp()
|
||||
|
||||
4.2.0 (2013-04-22)
|
||||
---------------------
|
||||
- fixed bug in SeedDMS_Core_DocumentContent::addIndApp()
|
||||
|
||||
4.1.3 (2013-04-08)
|
||||
---------------------
|
||||
- stay in sync with seeddms application
|
||||
|
||||
4.1.2 (2013-04-05)
|
||||
---------------------
|
||||
- set propper folderList of sub folders after moving a folder
|
||||
|
||||
4.1.1 (2013-04-05)
|
||||
---------------------
|
||||
- stay in sync with seeddms application
|
||||
|
||||
4.1.0 (2013-03-28)
|
||||
---------------------
|
||||
- minor bugfixes
|
||||
|
||||
4.0.0 (2013-02-26)
|
||||
---------------------
|
||||
- minor bugfixes
|
||||
|
||||
4.0.0pre5 (2013-02-14)
|
||||
---------------------
|
||||
- changed name from letodms to seeddms
|
||||
- fixed SeedDMS_Database::TableList()
|
||||
|
||||
4.0.0pre4 (2013-02-11)
|
||||
---------------------
|
||||
- calculate checksum for document versions
|
||||
- some bug fixes
|
||||
- some more documentation
|
||||
- added new methods SeedDMS_Core_Document::getReadUserList() and
|
||||
SeedDMS_Core_Folder::getReadUserList() which replaces getApproversList()
|
||||
- fixed sql statement in getReadUserList() for sqlite3
|
||||
|
||||
4.0.0pre3 (2013-02-08)
|
||||
---------------------
|
||||
- minor bug fixes
|
||||
|
||||
4.0.0pre2 (2013-02-06)
|
||||
---------------------
|
||||
- lots of bug fixes
|
||||
- replaced more of old var declaration
|
||||
- more code documentation
|
||||
|
||||
4.0.0pre1 (2013-01-24)
|
||||
---------------------
|
||||
- added database transactions
|
||||
- new workflow
|
||||
- replaced old var declaration
|
||||
|
||||
4.0.0RC1 (2013-02-20)
|
||||
---------------------
|
||||
- minor bugfixes
|
||||
|
||||
3.4.0 (2012-12-13)
|
||||
---------------------
|
||||
- added PDO database driver, several sql changes for better compatiblity
|
||||
- fixed bug when adding a new document category
|
||||
- make sure the database remains consistent even in case of errors
|
||||
|
||||
3.3.9 (2012-09-19)
|
||||
---------------------
|
||||
- version update to be in sync with letodms application
|
||||
|
||||
3.3.8 (2012-09-16)
|
||||
---------------------
|
||||
- more sql injection protection in LetoDMS_Core_User
|
||||
|
||||
3.3.7 (2012-08-25)
|
||||
---------------------
|
||||
- no changes, just keep same version as letodms application
|
||||
|
||||
3.3.6 (2012-07-16)
|
||||
---------------------
|
||||
- no changes, just keep same version as letodms application
|
||||
|
||||
3.3.5 (2012-04-30)
|
||||
---------------------
|
||||
- minor corrections
|
||||
|
||||
3.3.4 (2012-04-11)
|
||||
---------------------
|
||||
- fixed bug in LetoDMS_Core_DocumentFile::getPath()
|
||||
|
||||
3.3.3 (2012-03-28)
|
||||
---------------------
|
||||
- fixed bug in LetoDMS_Core_Document::getPath()
|
||||
|
||||
3.3.2 (2012-03-22)
|
||||
---------------------
|
||||
- fixed bug in LetoDMS_Core_Document::getDir()
|
||||
|
||||
3.3.1 (2012-03-21)
|
||||
---------------------
|
||||
- new release
|
||||
|
||||
3.3.0 (2012-02-08)
|
||||
---------------------
|
||||
- added methods to find and repair errors in document and folder records
|
||||
- removed sendmail parameter from some methods in LetoDMS_Core_Document
|
||||
- do not use some of the temporay tables anymore
|
||||
- SetFetchMode(ADODB_FETCH_ASSOC) in LetoDMS_Core_DatabaseAccess::connect()
|
||||
|
||||
3.2.0 (2011-07-23)
|
||||
---------------------
|
||||
New release
|
||||
|
||||
3.0.0 (2010-04-27)
|
||||
---------------------
|
||||
Initial release
|
||||
|
3
SeedDMS_Core/bootstrap-5.php
Normal file
3
SeedDMS_Core/bootstrap-5.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
// Do any kind of bootstraping for major database version 5
|
||||
$majorversion = 5; // just an example, currently not used
|
3
SeedDMS_Core/bootstrap-6.php
Normal file
3
SeedDMS_Core/bootstrap-6.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
// Do any kind of bootstraping for major database version 6
|
||||
$majorversion = 6; // just an example, currently not used
|
23
SeedDMS_Core/composer.json
Normal file
23
SeedDMS_Core/composer.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "seeddms/core",
|
||||
"description": "Core classes to access a SeedDMS database",
|
||||
"type": "library",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"minimum-stability": "dev",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Seeddms\\Core\\": "Core/"
|
||||
},
|
||||
"classmap": ["Core/"]
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Uwe Steinmann",
|
||||
"email": "info@seeddms.org"
|
||||
}
|
||||
],
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9"
|
||||
}
|
||||
|
||||
}
|
26
SeedDMS_Core/phpunit.xml
Normal file
26
SeedDMS_Core/phpunit.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
|
||||
cacheResultFile=".phpunit.cache/test-results"
|
||||
executionOrder="depends,defects"
|
||||
forceCoversAnnotation="false"
|
||||
beStrictAboutCoversAnnotation="false"
|
||||
beStrictAboutOutputDuringTests="false"
|
||||
beStrictAboutTodoAnnotatedTests="false"
|
||||
failOnRisky="false"
|
||||
failOnWarning="true"
|
||||
verbose="true">
|
||||
<testsuites>
|
||||
<testsuite name="default">
|
||||
<directory suffix="Test.php">tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<coverage cacheDirectory=".phpunit.cache/code-coverage"
|
||||
includeUncoveredFiles="true"
|
||||
processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">Core</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
</phpunit>
|
1
SeedDMS_Core/tests/.phpunit.result.cache
Normal file
1
SeedDMS_Core/tests/.phpunit.result.cache
Normal file
|
@ -0,0 +1 @@
|
|||
C:37:"PHPUnit\Runner\DefaultTestResultCache":106:{a:2:{s:7:"defects";a:1:{s:17:"DmsTest::testInit";i:3;}s:5:"times";a:1:{s:17:"DmsTest::testInit";d:0.002;}}}
|
574
SeedDMS_Core/tests/AttributeDefinitionTest.php
Normal file
574
SeedDMS_Core/tests/AttributeDefinitionTest.php
Normal file
|
@ -0,0 +1,574 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the attribute definiton tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Attribute definition test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class AttributeDefinitionTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real dms object with a mocked db
|
||||
*
|
||||
* This mock is only used if \SeedDMS_Core_DatabaseAccess::getResult() is
|
||||
* called once. This is the case for all \SeedDMS_Core_AttributeDefinition::setXXX()
|
||||
* methods like setName().
|
||||
*
|
||||
* @return \SeedDMS_Core_DMS
|
||||
*/
|
||||
protected function getDmsWithMockedDb() : \SeedDMS_Core_DMS
|
||||
{
|
||||
$db = $this->createMock(\SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE "))
|
||||
->willReturn(true);
|
||||
$dms = new \SeedDMS_Core_DMS($db, '');
|
||||
return $dms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mocked dms
|
||||
*
|
||||
* @return \SeedDMS_Core_DMS
|
||||
*/
|
||||
protected function getDmsMock() : \SeedDMS_Core_DMS
|
||||
{
|
||||
$dms = $this->createMock(\SeedDMS_Core_DMS::class);
|
||||
$dms->expects($this->any())
|
||||
->method('getDocument')
|
||||
->with(1)
|
||||
->willReturn(true);
|
||||
$dms->expects($this->any())
|
||||
->method('getFolder')
|
||||
->with(1)
|
||||
->willReturn(true);
|
||||
$dms->expects($this->any())
|
||||
->method('getUser')
|
||||
->will(
|
||||
$this->returnValueMap(
|
||||
array(
|
||||
array(1, new \SeedDMS_Core_User(1, 'admin', 'pass', 'Joe Foo', 'baz@foo.de', 'en_GB', 'bootstrap', 'My comment', \SeedDMS_Core_User::role_admin)),
|
||||
array(2, new \SeedDMS_Core_User(2, 'admin2', 'pass', 'Joe Bar', 'bar@foo.de', 'en_GB', 'bootstrap', 'My comment', \SeedDMS_Core_User::role_admin)),
|
||||
array(3, null)
|
||||
)
|
||||
)
|
||||
);
|
||||
$dms->expects($this->any())
|
||||
->method('getGroup')
|
||||
->will(
|
||||
$this->returnValueMap(
|
||||
array(
|
||||
array(1, new \SeedDMS_Core_Group(1, 'admin group 1', 'My comment')),
|
||||
array(2, new \SeedDMS_Core_Group(2, 'admin group 2', 'My comment')),
|
||||
array(3, null)
|
||||
)
|
||||
)
|
||||
);
|
||||
return $dms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock attribute definition object
|
||||
*
|
||||
* @param int $type type of attribute
|
||||
* @param boolean $multiple set to true for multi value attributes
|
||||
* @param int $minvalues minimum number of attribute values
|
||||
* @param int $maxvalues maximum number of attribute values
|
||||
* @param string $valueset list of allowed values separated by the first char
|
||||
* @param string $regex regular expression that must match the attribute value
|
||||
*
|
||||
* @return \SeedDMS_Core_AttributeDefinition
|
||||
*/
|
||||
protected function getAttributeDefinition($type, $multiple=false, $minvalues=0, $maxvalues=0, $valueset='', $regex='')
|
||||
{
|
||||
$attrdef = new \SeedDMS_Core_AttributeDefinition(1, 'foo attr', \SeedDMS_Core_AttributeDefinition::objtype_folder, $type, $multiple, $minvalues, $maxvalues, $valueset, $regex);
|
||||
return $attrdef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getId()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetId()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEquals(1, $attrdef->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getName()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetName()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEquals('foo attr', $attrdef->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setName()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetName()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
$attrdef->setName('bar attr');
|
||||
$this->assertEquals('bar attr', $attrdef->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getObjType()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetObjType()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::objtype_folder, $attrdef->getObjType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setObjType()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetObjType()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
$attrdef->setObjType(\SeedDMS_Core_AttributeDefinition::objtype_document);
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::objtype_document, $attrdef->getObjType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getType()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetType()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::type_int, $attrdef->getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setType()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetType()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
$attrdef->setType(\SeedDMS_Core_AttributeDefinition::type_string);
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::type_string, $attrdef->getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getMultipleValues()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMultipleValues()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEquals(false, $attrdef->getMultipleValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setMultipleValues()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetMultipleValues()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
/* Toogle the current value of multiple values */
|
||||
$oldvalue = $attrdef->getMultipleValues();
|
||||
$attrdef->setMultipleValues(!$oldvalue);
|
||||
$this->assertEquals(!$oldvalue, $attrdef->getMultipleValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getMinValues()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMinValues()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEquals(0, $attrdef->getMinValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setMinValues()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetMinValues()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
/* add 5 to value of min values */
|
||||
$oldvalue = $attrdef->getMinValues();
|
||||
$attrdef->setMinValues($oldvalue+5);
|
||||
$this->assertEquals($oldvalue+5, $attrdef->getMinValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getMaxValues()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMaxValues()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEquals(0, $attrdef->getMaxValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setMaxValues()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetMaxValues()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
/* add 5 to value of max values */
|
||||
$oldvalue = $attrdef->getMaxValues();
|
||||
$attrdef->setMaxValues($oldvalue+5);
|
||||
$this->assertEquals($oldvalue+5, $attrdef->getMaxValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getValueSet()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetValueSet()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '|foo|bar|baz');
|
||||
$this->assertEquals('|foo|bar|baz', $attrdef->getValueSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getValueSetSeparator()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetValueSetSeparator()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '|foo|bar|baz');
|
||||
$this->assertEquals('|', $attrdef->getValueSetSeparator());
|
||||
/* No value set will return no separator */
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertEmpty($attrdef->getValueSetSeparator());
|
||||
/* Even a 1 char value set will return no separator */
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '|');
|
||||
$this->assertEmpty($attrdef->getValueSetSeparator());
|
||||
/* Multiple users or groups always use a ',' as a separator */
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_user, true);
|
||||
$this->assertEquals(',', $attrdef->getValueSetSeparator());
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_group, true);
|
||||
$this->assertEquals(',', $attrdef->getValueSetSeparator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getValueSetAsArray()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetValueSetAsArray()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '|foo|bar|baz ');
|
||||
$valueset = $attrdef->getValueSetAsArray();
|
||||
$this->assertIsArray($valueset);
|
||||
$this->assertCount(3, $valueset);
|
||||
/* value set must contain 'baz' though 'baz ' was originally set */
|
||||
$this->assertContains('baz', $valueset);
|
||||
/* No value set will return an empty array */
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string);
|
||||
$valueset = $attrdef->getValueSetAsArray();
|
||||
$this->assertIsArray($valueset);
|
||||
$this->assertEmpty($valueset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getValueSetValue()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetValueSetValue()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '|foo|bar|baz ');
|
||||
$this->assertEquals('foo', $attrdef->getValueSetValue(0));
|
||||
/* Check if trimming of 'baz ' worked */
|
||||
$this->assertEquals('baz', $attrdef->getValueSetValue(2));
|
||||
/* Getting the value of a none existing index returns false */
|
||||
$this->assertFalse($attrdef->getValueSetValue(3));
|
||||
|
||||
/* Getting a value from a none existing value set returns false as well */
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string);
|
||||
$this->assertFalse($attrdef->getValueSetValue(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setValueSet()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetValueSet()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
/* add 5 to value of min values */
|
||||
$attrdef->setValueSet(' |foo|bar | baz ');
|
||||
$this->assertEquals('|foo|bar|baz', $attrdef->getValueSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getRegex()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetRegex()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '', '[0-9].*');
|
||||
$this->assertEquals('[0-9].*', $attrdef->getRegex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setRegex()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetRegex()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
/* set a new valid regex */
|
||||
$this->assertTrue($attrdef->setRegex(' /[0-9].*/i '));
|
||||
$this->assertEquals('/[0-9].*/i', $attrdef->getRegex());
|
||||
/* set a new invalid regex will return false and keep the old regex */
|
||||
$this->assertFalse($attrdef->setRegex(' /([0-9].*/i '));
|
||||
$this->assertEquals('/[0-9].*/i', $attrdef->getRegex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setEmptyRegex()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetEmptyRegex()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string);
|
||||
/* A mocked dms is needed for updating the database */
|
||||
$attrdef->setDMS(self::getDmsWithMockedDb());
|
||||
/* set an empty regex */
|
||||
$this->assertTrue($attrdef->setRegex(''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parseValue()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testParseValue()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string);
|
||||
$value = $attrdef->parseValue('foo');
|
||||
$this->assertIsArray($value);
|
||||
$this->assertCount(1, $value);
|
||||
$this->assertContains('foo', $value);
|
||||
/* An attribute definition with multiple values will split the value by the first char */
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, true, 0, 0, '|baz|bar|foo');
|
||||
$value = $attrdef->parseValue('|bar|baz');
|
||||
$this->assertIsArray($value);
|
||||
$this->assertCount(2, $value);
|
||||
/* An attribute definition without multiple values, will treat the value as a string */
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '|baz|bar|foo');
|
||||
$value = $attrdef->parseValue('|bar|baz');
|
||||
$this->assertIsArray($value);
|
||||
$this->assertCount(1, $value);
|
||||
$this->assertContains('|bar|baz', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test validate()
|
||||
*
|
||||
* @TODO Instead of having a lengthy list of assert calls, this could be
|
||||
* implemented with data providers for each attribute type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testValidate()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string);
|
||||
$this->assertTrue($attrdef->validate('')); // even an empty string is valid
|
||||
$this->assertTrue($attrdef->validate('foo')); // there is no invalid string
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '', '/[0-9]*S/');
|
||||
$this->assertFalse($attrdef->validate('foo')); // doesn't match the regex
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_regex, $attrdef->getValidationError());
|
||||
$this->assertTrue($attrdef->validate('S')); // no leading numbers needed
|
||||
$this->assertTrue($attrdef->validate('8980S')); // leading numbers are ok
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, false, 0, 0, '|foo|bar|baz', '');
|
||||
$this->assertTrue($attrdef->validate('foo')); // is part of value map
|
||||
$this->assertFalse($attrdef->validate('foz')); // is not part of value map
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_valueset, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, true, 0, 0, '|foo|bar|baz', '');
|
||||
$this->assertTrue($attrdef->validate('foo')); // is part of value map
|
||||
$this->assertFalse($attrdef->validate('')); // an empty value cannot be in the valueset
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_valueset, $attrdef->getValidationError());
|
||||
$this->assertTrue($attrdef->validate('|foo|baz')); // both are part of value map
|
||||
$this->assertFalse($attrdef->validate('|foz|baz')); // 'foz' is not part of value map
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_valueset, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_string, true, 1, 1, '|foo|bar|baz', '');
|
||||
$this->assertTrue($attrdef->validate('foo')); // is part of value map
|
||||
$this->assertFalse($attrdef->validate('')); // empty string is invalid because of min values = 1
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_min_values, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('|foo|baz')); // both are part of value map, but only value is allowed
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_max_values, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_boolean);
|
||||
$this->assertTrue($attrdef->validate(0));
|
||||
$this->assertTrue($attrdef->validate(1));
|
||||
$this->assertFalse($attrdef->validate(2));
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_boolean, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$this->assertTrue($attrdef->validate(0));
|
||||
$this->assertTrue($attrdef->validate('0'));
|
||||
$this->assertFalse($attrdef->validate('a'));
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_int, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_date);
|
||||
$this->assertTrue($attrdef->validate('2021-09-30'));
|
||||
$this->assertTrue($attrdef->validate('1968-02-29')); // 1968 was a leap year
|
||||
$this->assertTrue($attrdef->validate('2000-02-29')); // 2000 was a leap year
|
||||
$this->assertFalse($attrdef->validate('1900-02-29')); // 1900 didn't was a leap year
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_date, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('1970-02-29')); // 1970 didn't was a leap year
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_date, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('2010/02/28')); // This has the wrong format
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_date, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('1970-00-29')); // 0 month is not allowed
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_date, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('1970-01-00')); // 0 day is not allowed
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_date, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_float);
|
||||
$this->assertTrue($attrdef->validate('0.567'));
|
||||
$this->assertTrue($attrdef->validate('1000'));
|
||||
$this->assertTrue($attrdef->validate('1000e3'));
|
||||
$this->assertTrue($attrdef->validate('1000e-3'));
|
||||
$this->assertTrue($attrdef->validate('-1000'));
|
||||
$this->assertTrue($attrdef->validate('+1000'));
|
||||
$this->assertFalse($attrdef->validate('0,567')); // wrong decimal point
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_float, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('0.56.7')); // two decimal point
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_float, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_email);
|
||||
$this->assertTrue($attrdef->validate('info@seeddms.org'));
|
||||
$this->assertTrue($attrdef->validate('info@seeddms.verylongtopleveldomain'));
|
||||
$this->assertFalse($attrdef->validate('@seeddms.org')); // no user
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_email, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('info@localhost')); // no tld
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_email, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('info@@seeddms.org')); // double @
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_email, $attrdef->getValidationError());
|
||||
$this->assertTrue($attrdef->validate('info@subsubdomain.subdomain.seeddms.org')); // multiple subdomains are ok
|
||||
$this->assertFalse($attrdef->validate('info@seeddms..org')); // double . is not allowed
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_email, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('info@s.org')); // 2nd level domain name is too short
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_email, $attrdef->getValidationError());
|
||||
$this->assertFalse($attrdef->validate('info@seeddms.o')); // top level domain name is too short
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_email, $attrdef->getValidationError());
|
||||
$this->assertTrue($attrdef->validate('info@0123456789-0123456789-0123456789-0123456789-0123456789-01234567.org')); // domain name is 63 chars long, which is the max length
|
||||
$this->assertFalse($attrdef->validate('info@0123456789-0123456789-0123456789-0123456789-0123456789-012345678.org')); // domain name is 1 char longer than 63 chars
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_email, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_url);
|
||||
$this->assertTrue($attrdef->validate('http://seeddms.org'));
|
||||
$this->assertTrue($attrdef->validate('https://seeddms.org'));
|
||||
$this->assertFalse($attrdef->validate('ftp://seeddms.org')); // ftp is not allowed
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_url, $attrdef->getValidationError());
|
||||
$this->assertTrue($attrdef->validate('http://localhost')); // no tld is just fine
|
||||
$this->assertFalse($attrdef->validate('http://localhost.o')); // tld is to short
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_url, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_user);
|
||||
$attrdef->setDMS(self::getDmsMock());
|
||||
$this->assertTrue($attrdef->validate(1));
|
||||
$this->assertFalse($attrdef->validate(3));
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_user, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_group);
|
||||
$attrdef->setDMS(self::getDmsMock());
|
||||
$this->assertTrue($attrdef->validate('1'));
|
||||
$this->assertTrue($attrdef->validate('2'));
|
||||
$this->assertFalse($attrdef->validate('3')); // there is no group with id=3
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_group, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_group, true);
|
||||
$attrdef->setDMS(self::getDmsMock());
|
||||
$this->assertTrue($attrdef->validate(',1,2'));
|
||||
$this->assertFalse($attrdef->validate(',1,2,3')); // there is no group with id=3
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_group, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_user);
|
||||
$attrdef->setDMS(self::getDmsMock());
|
||||
$this->assertTrue($attrdef->validate('1'));
|
||||
$this->assertTrue($attrdef->validate('2'));
|
||||
$this->assertFalse($attrdef->validate('3')); // there is no user with id=3
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_user, $attrdef->getValidationError());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(\SeedDMS_Core_AttributeDefinition::type_user, true);
|
||||
$attrdef->setDMS(self::getDmsMock());
|
||||
$this->assertTrue($attrdef->validate(',1,2'));
|
||||
$this->assertFalse($attrdef->validate(',1,2,3')); // there is no user with id=3
|
||||
$this->assertEquals(\SeedDMS_Core_AttributeDefinition::val_error_user, $attrdef->getValidationError());
|
||||
}
|
||||
|
||||
}
|
155
SeedDMS_Core/tests/AttributeTest.php
Normal file
155
SeedDMS_Core/tests/AttributeTest.php
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the attribute tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Attribute and attribute definition test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class AttributeTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a mock dms object
|
||||
*
|
||||
* @return SeedDMS_Core_DMS
|
||||
*/
|
||||
protected function getMockDMS() : SeedDMS_Core_DMS
|
||||
{
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->any())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE "))
|
||||
->willReturn(true);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
return $dms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock attribute definition object
|
||||
*
|
||||
* @param int $type type of attribute
|
||||
* @param boolean $multiple true if multiple values are allowed
|
||||
* @param int $minvalues minimum number of required values
|
||||
* @param int $maxvalues maximum number of required value
|
||||
* @param string $valueset list of allowed values separated by the first char
|
||||
* @param string $regex regular expression the attribute value must match
|
||||
*
|
||||
* @return SeedDMS_Core_AttributeDefinition
|
||||
*/
|
||||
protected function getAttributeDefinition($type, $multiple=false, $minvalues=0, $maxvalues=0, $valueset='', $regex='')
|
||||
{
|
||||
$attrdef = new SeedDMS_Core_AttributeDefinition(1, 'foo attrdef', SeedDMS_Core_AttributeDefinition::objtype_folder, $type, $multiple, $minvalues, $maxvalues, $valueset, $regex);
|
||||
return $attrdef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock attribute object
|
||||
*
|
||||
* @param SeedDMS_Core_AttributeDefinition $attrdef attribute defintion of attribute
|
||||
* @param mixed $value value of attribute
|
||||
*
|
||||
* @return SeedDMS_Core_Attribute
|
||||
*/
|
||||
static protected function getAttribute($attrdef, $value)
|
||||
{
|
||||
$folder = new SeedDMS_Core_Folder(1, 'Folder', null, '', '', '', 0, 0, 0);
|
||||
$attribute = new SeedDMS_Core_Attribute(1, $folder, $attrdef, $value);
|
||||
$attribute->setDMS($attrdef->getDMS());
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getId()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetId()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$attribute = self::getAttribute($attrdef, '');
|
||||
$this->assertEquals(1, $attribute->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getValue()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetValue()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$attribute = self::getAttribute($attrdef, 7);
|
||||
$this->assertEquals(7, $attribute->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getValueAsArray()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetValueAsArray()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$attribute = self::getAttribute($attrdef, 7);
|
||||
$this->assertIsArray($attribute->getValueAsArray());
|
||||
$this->assertCount(1, $attribute->getValueAsArray());
|
||||
$this->assertContains(7, $attribute->getValueAsArray());
|
||||
|
||||
/* Test a multi value integer */
|
||||
$attrdef = self::getAttributeDefinition(SeedDMS_Core_AttributeDefinition::type_int, true);
|
||||
$attribute = self::getAttribute($attrdef, ',3,4,6');
|
||||
$value = $attribute->getValueAsArray();
|
||||
$this->assertIsArray($attribute->getValueAsArray());
|
||||
$this->assertCount(3, $attribute->getValueAsArray());
|
||||
$this->assertContains('6', $attribute->getValueAsArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setValue()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetValue()
|
||||
{
|
||||
$attrdef = self::getAttributeDefinition(SeedDMS_Core_AttributeDefinition::type_int);
|
||||
$attrdef->setDMS(self::getMockDMS());
|
||||
$attribute = self::getAttribute($attrdef, 0);
|
||||
$this->assertTrue($attribute->setValue(9));
|
||||
$this->assertEquals(9, $attribute->getValue());
|
||||
/* Setting an array of values for a none multi value attribute will just take the
|
||||
* element of the array.
|
||||
*/
|
||||
$this->assertTrue($attribute->setValue([8,9]));
|
||||
$this->assertEquals(8, $attribute->getValue());
|
||||
|
||||
$attrdef = self::getAttributeDefinition(SeedDMS_Core_AttributeDefinition::type_int, true);
|
||||
$attrdef->setDMS(self::getMockDMS());
|
||||
$attribute = self::getAttribute($attrdef, ',3,4,6');
|
||||
$attribute->setValue([8,9,10]);
|
||||
$this->assertEquals(',8,9,10', $attribute->getValue());
|
||||
$this->assertIsArray($attribute->getValueAsArray());
|
||||
$this->assertCount(3, $attribute->getValueAsArray());
|
||||
$this->assertContains('9', $attribute->getValueAsArray());
|
||||
}
|
||||
}
|
324
SeedDMS_Core/tests/DatabaseTest.php
Normal file
324
SeedDMS_Core/tests/DatabaseTest.php
Normal file
|
@ -0,0 +1,324 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the low level database tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
namespace PHPUnit\Framework;
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
require_once('SeedDmsBase.php');
|
||||
|
||||
/**
|
||||
* Low level Database test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class DatabaseTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if connection to database exists
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsConnected()
|
||||
{
|
||||
$this->assertTrue(self::$dbh->ensureConnected());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for number of tables in database
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTableList()
|
||||
{
|
||||
$tablelist = self::$dbh->TableList();
|
||||
$this->assertIsArray($tablelist);
|
||||
// There are just 42 tables in SeedDMS5 and 55 tables in SeedDMS6,
|
||||
// but one additional
|
||||
// table 'sqlite_sequence'
|
||||
$dms = new \SeedDMS_Core_DMS(null, '');
|
||||
if($dms->version[0] == '5')
|
||||
$this->assertCount(43, $tablelist);
|
||||
else
|
||||
$this->assertCount(56, $tablelist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test createTemporaryTable()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateTemporaryTable()
|
||||
{
|
||||
foreach (['ttreviewid', 'ttapproveid', 'ttstatid', 'ttcontentid'] as $temp) {
|
||||
$ret = self::$dbh->createTemporaryTable($temp);
|
||||
$rec = self::$dbh->getResultArray("SELECT * FROM `".$temp."`");
|
||||
$this->assertIsArray($rec);
|
||||
}
|
||||
/* Running it again will not harm */
|
||||
foreach (['ttreviewid', 'ttapproveid', 'ttstatid', 'ttcontentid'] as $temp) {
|
||||
$ret = self::$dbh->createTemporaryTable($temp);
|
||||
$rec = self::$dbh->getResultArray("SELECT * FROM `".$temp."`");
|
||||
$this->assertIsArray($rec);
|
||||
}
|
||||
/* Running it again and overwrite the old table contents */
|
||||
foreach (['ttreviewid', 'ttapproveid', 'ttstatid', 'ttcontentid'] as $temp) {
|
||||
$ret = self::$dbh->createTemporaryTable($temp, true);
|
||||
$rec = self::$dbh->getResultArray("SELECT * FROM `".$temp."`");
|
||||
$this->assertIsArray($rec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test createTemporaryTable() based on views
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateTemporaryTableBasedOnViews()
|
||||
{
|
||||
self::$dbh->useViews(true);
|
||||
foreach (['ttreviewid', 'ttapproveid', 'ttstatid', 'ttcontentid'] as $temp) {
|
||||
$ret = self::$dbh->createTemporaryTable($temp);
|
||||
$rec = self::$dbh->getResultArray("SELECT * FROM `".$temp."`");
|
||||
$this->assertIsArray($rec);
|
||||
}
|
||||
$viewlist = self::$dbh->ViewList();
|
||||
$this->assertIsArray($viewlist);
|
||||
$this->assertCount(4, $viewlist);
|
||||
|
||||
/* Running it again will not harm */
|
||||
foreach (['ttreviewid', 'ttapproveid', 'ttstatid', 'ttcontentid'] as $temp) {
|
||||
$ret = self::$dbh->createTemporaryTable($temp);
|
||||
$rec = self::$dbh->getResultArray("SELECT * FROM `".$temp."`");
|
||||
$this->assertIsArray($rec);
|
||||
}
|
||||
/* Running it again and replace the old view */
|
||||
foreach (['ttreviewid', 'ttapproveid', 'ttstatid', 'ttcontentid'] as $temp) {
|
||||
$ret = self::$dbh->createTemporaryTable($temp, true);
|
||||
$rec = self::$dbh->getResultArray("SELECT * FROM `".$temp."`");
|
||||
$this->assertIsArray($rec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for number of views in database
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testViewList()
|
||||
{
|
||||
$viewlist = self::$dbh->ViewList();
|
||||
$this->assertIsArray($viewlist);
|
||||
// There are 0 views
|
||||
$this->assertCount(0, $viewlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getDriver()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetDriver()
|
||||
{
|
||||
$driver = self::$dbh->getDriver();
|
||||
$this->assertEquals('sqlite', $driver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test rbt()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRbt()
|
||||
{
|
||||
$str = self::$dbh->rbt("SELECT * FROM `tblUsers`");
|
||||
$this->assertEquals('SELECT * FROM "tblUsers"', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if table tblFolders has root folder
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testInitialRootFolder()
|
||||
{
|
||||
$this->assertTrue(self::$dbh->hasTable('tblFolders'));
|
||||
$query = 'SELECT * FROM `tblFolders`';
|
||||
$recs = self::$dbh->getResultArray($query);
|
||||
$this->assertIsArray($recs);
|
||||
$this->assertCount(1, $recs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if table tblUsers has two initial users
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testInitialUsers()
|
||||
{
|
||||
$this->assertTrue(self::$dbh->hasTable('tblUsers'));
|
||||
$query = 'SELECT * FROM `tblUsers`';
|
||||
$recs = self::$dbh->getResultArray($query);
|
||||
$this->assertIsArray($recs);
|
||||
$this->assertCount(2, $recs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getCurrentDatetime()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetCurrentDatetime()
|
||||
{
|
||||
$query = 'SELECT '.self::$dbh->getCurrentDatetime().' as a';
|
||||
$recs = self::$dbh->getResultArray($query);
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$this->assertIsArray($recs);
|
||||
$this->assertEquals($now, $recs[0]['a'], 'Make sure php.ini has the proper timezone configured');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getCurrentTimestamp()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetCurrentTimestamp()
|
||||
{
|
||||
$query = 'SELECT '.self::$dbh->getCurrentTimestamp().' as a';
|
||||
$recs = self::$dbh->getResultArray($query);
|
||||
$now = time();
|
||||
$this->assertIsArray($recs);
|
||||
$this->assertEquals($now, $recs[0]['a'], 'Make sure php.ini has the proper timezone configured');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test concat()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConcat()
|
||||
{
|
||||
$query = 'SELECT '.self::$dbh->concat(["'foo'", "'baz'", "'bar'"]).' as a';
|
||||
$recs = self::$dbh->getResultArray($query);
|
||||
$this->assertIsArray($recs);
|
||||
$this->assertEquals('foobazbar', $recs[0]['a']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test qstr()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testQstr()
|
||||
{
|
||||
$str = self::$dbh->qstr("bar");
|
||||
$this->assertEquals("'bar'", $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getResult() if the sql fails
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetResultSqlFail()
|
||||
{
|
||||
$ret = self::$dbh->getResult("UPDATE FOO SET `name`='foo'");
|
||||
$this->assertFalse($ret);
|
||||
$errmsg = self::$dbh->getErrorMsg();
|
||||
$this->assertStringContainsString('no such table: FOO', $errmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getResultArray() if the sql fails
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetResultArraySqlFail()
|
||||
{
|
||||
$ret = self::$dbh->getResultArray("SELECT * FROM FOO");
|
||||
$this->assertFalse($ret);
|
||||
$errmsg = self::$dbh->getErrorMsg();
|
||||
$this->assertStringContainsString('no such table: FOO', $errmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test logging into file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLogging()
|
||||
{
|
||||
$fp = fopen('php://memory', 'r+');
|
||||
self::$dbh->setLogFp($fp);
|
||||
$sql = "SELECT * FROM `tblUsers`";
|
||||
$ret = self::$dbh->getResultArray($sql);
|
||||
$this->assertIsArray($ret);
|
||||
fseek($fp, 0);
|
||||
$contents = fread($fp, 200);
|
||||
/* Check if sql statement was logged into file */
|
||||
$this->assertStringContainsString($sql, $contents);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test createDump()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateDump()
|
||||
{
|
||||
$fp = fopen('php://memory', 'r+');
|
||||
$ret = self::$dbh->createDump($fp);
|
||||
$this->assertTrue($ret);
|
||||
$stat = fstat($fp);
|
||||
$this->assertIsArray($stat);
|
||||
$dms = new \SeedDMS_Core_DMS(null, '');
|
||||
if($dms->version[0] == '5')
|
||||
$this->assertEquals(1724, $stat['size']);
|
||||
else
|
||||
$this->assertEquals(2272, $stat['size']);
|
||||
// fseek($fp, 0);
|
||||
// echo fread($fp, 200);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
2956
SeedDMS_Core/tests/DmsTest.php
Normal file
2956
SeedDMS_Core/tests/DmsTest.php
Normal file
File diff suppressed because it is too large
Load Diff
290
SeedDMS_Core/tests/DmsWithDataTest.php
Normal file
290
SeedDMS_Core/tests/DmsWithDataTest.php
Normal file
|
@ -0,0 +1,290 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the complex dms tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* DMS test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class DmsWithDataTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getFoldersMinMax()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetFoldersMinMax()
|
||||
{
|
||||
self::createSimpleFolderStructure();
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$minmax = $rootfolder->getFoldersMinMax();
|
||||
$this->assertIsArray($minmax);
|
||||
$this->assertCount(2, $minmax);
|
||||
$this->assertEquals(0.5, $minmax['min']);
|
||||
$this->assertEquals(2.0, $minmax['max']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getFoldersMinMax()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetFoldersMinMaxSqlFail()
|
||||
{
|
||||
$rootfolder = $this->getMockedRootFolder();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT min(`sequence`) AS `min`, max(`sequence`) AS `max` FROM `tblFolders`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$rootfolder->setDMS($dms);
|
||||
$this->assertFalse($rootfolder->getFoldersMinMax());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getDocumentsMinMax()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetDocumentsMinMax()
|
||||
{
|
||||
self::createSimpleFolderStructureWithDocuments();
|
||||
$subfolder = self::$dms->getFolderByName('Subfolder 1');
|
||||
$this->assertIsObject($subfolder);
|
||||
$minmax = $subfolder->getDocumentsMinMax();
|
||||
$this->assertIsArray($minmax);
|
||||
$this->assertCount(2, $minmax);
|
||||
$this->assertEquals(2.0, $minmax['min']);
|
||||
$this->assertEquals(16.0, $minmax['max']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getDocumentsMinMax()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetDocumentsMinMaxSqlFail()
|
||||
{
|
||||
$rootfolder = $this->getMockedRootFolder();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT min(`sequence`) AS `min`, max(`sequence`) AS `max` FROM `tblDocuments`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$rootfolder->setDMS($dms);
|
||||
$this->assertFalse($rootfolder->getDocumentsMinMax());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test addDocument()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAddDocument()
|
||||
{
|
||||
self::createSimpleFolderStructure();
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertInstanceOf(SeedDMS_Core_Folder::class, $rootfolder);
|
||||
$this->assertEquals(1, $rootfolder->getId());
|
||||
/* Add a new document */
|
||||
$filename = self::createTempFile(200);
|
||||
list($document, $res) = $rootfolder->addDocument(
|
||||
'Document 1', // name
|
||||
'', // comment
|
||||
null, // expiration
|
||||
$user, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file1.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0 // sequence
|
||||
);
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($filename));
|
||||
$this->assertIsObject($document);
|
||||
$this->assertInstanceOf(SeedDMS_Core_Document::class, $document);
|
||||
$this->assertEquals('Document 1', $document->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getDocumentsExpired()
|
||||
*
|
||||
* Create two documents which will expired today and tomorrow
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetDocumentsExpiredFuture()
|
||||
{
|
||||
self::createSimpleFolderStructure();
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertInstanceOf(SeedDMS_Core_Folder::class, $rootfolder);
|
||||
$this->assertEquals(1, $rootfolder->getId());
|
||||
/* Add a new document */
|
||||
$filename = self::createTempFile(200);
|
||||
list($document, $res) = $rootfolder->addDocument(
|
||||
'Document 1', // name
|
||||
'', // comment
|
||||
mktime(23,59,59), // expiration is still today at 23:59:59
|
||||
$user, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file1.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0 // sequence
|
||||
);
|
||||
$this->assertIsObject($document);
|
||||
list($document, $res) = $rootfolder->addDocument(
|
||||
'Document 2', // name
|
||||
'', // comment
|
||||
mktime(23,59,59)+1, // expiration is tomorrow today at 0:00:00
|
||||
$user, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file1.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0 // sequence
|
||||
);
|
||||
$this->assertIsObject($document);
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($filename));
|
||||
$documents = self::$dms->getDocumentsExpired(0); /* Docs expire today */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(1, $documents);
|
||||
$documents = self::$dms->getDocumentsExpired(date('Y-m-d')); /* Docs expire today */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(1, $documents);
|
||||
$documents = self::$dms->getDocumentsExpired(1); /* Docs expire till tomorrow 23:59:59 */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(2, $documents);
|
||||
$documents = self::$dms->getDocumentsExpired(date('Y-m-d', time()+86400)); /* Docs expire till tomorrow 23:59:59 */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(2, $documents);
|
||||
$documents = self::$dms->getDocumentsExpired(date('Y-m-d', time()+86400), $user); /* Docs expire till tomorrow 23:59:59 owned by $user */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(2, $documents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getDocumentsExpired()
|
||||
*
|
||||
* Create two documents which have expired yesterday and the day before
|
||||
* yesterday
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetDocumentsExpiredPast()
|
||||
{
|
||||
self::createSimpleFolderStructure();
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertInstanceOf(SeedDMS_Core_Folder::class, $rootfolder);
|
||||
$this->assertEquals(1, $rootfolder->getId());
|
||||
/* Add a new document */
|
||||
$filename = self::createTempFile(200);
|
||||
list($document, $res) = $rootfolder->addDocument(
|
||||
'Document 1', // name
|
||||
'', // comment
|
||||
mktime(0,0,0)-1, // expiration was yesterday
|
||||
$user, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file1.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0 // sequence
|
||||
);
|
||||
$this->assertIsObject($document);
|
||||
list($document, $res) = $rootfolder->addDocument(
|
||||
'Document 2', // name
|
||||
'', // comment
|
||||
mktime(0,0,0)-1-86400, // expiration the day before yesterday
|
||||
$user, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file1.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0 // sequence
|
||||
);
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($filename));
|
||||
$this->assertIsObject($document);
|
||||
$documents = self::$dms->getDocumentsExpired(0); /* No Docs expire today */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(0, $documents);
|
||||
$documents = self::$dms->getDocumentsExpired(-1); /* Docs expired yesterday */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(1, $documents);
|
||||
$documents = self::$dms->getDocumentsExpired(-2); /* Docs expired since the day before yesterday */
|
||||
$this->assertIsArray($documents);
|
||||
$this->assertCount(2, $documents);
|
||||
}
|
||||
|
||||
|
||||
}
|
295
SeedDMS_Core/tests/DocumentCategoryTest.php
Normal file
295
SeedDMS_Core/tests/DocumentCategoryTest.php
Normal file
|
@ -0,0 +1,295 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the category tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* User test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class DocumentCategoryTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getName() and setName()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetName()
|
||||
{
|
||||
$user = SeedDMS_Core_User::getInstance(1, self::$dms);
|
||||
$cat = self::$dms->addDocumentCategory('Category 1');
|
||||
$name = $cat->getName();
|
||||
$ret = $cat->setName('foo');
|
||||
$this->assertTrue($ret);
|
||||
$name = $cat->getName();
|
||||
$this->assertEquals('foo', $name);
|
||||
$ret = $cat->setName(' ');
|
||||
$this->assertFalse($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addCategories(), hasCategory(), setCategory()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAddCategoryToDocument()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = SeedDMS_Core_User::getInstance(1, self::$dms);
|
||||
|
||||
/* Add a new document and two categories */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$cat1 = self::$dms->addDocumentCategory('Category 1');
|
||||
$cat2 = self::$dms->addDocumentCategory('Category 2');
|
||||
|
||||
/* There are no categories yet */
|
||||
$ret = $document->hasCategory($cat1);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* Not passing a category yields on error */
|
||||
$ret = $document->hasCategory(null);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* Adding a category ... */
|
||||
$ret = $document->addCategories([$cat1]);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* ... and check if it is there */
|
||||
$ret = $document->hasCategory($cat1);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* There should be one category now */
|
||||
$cats = $document->getCategories();
|
||||
$this->assertIsArray($cats);
|
||||
$this->assertCount(1, $cats);
|
||||
$this->assertEquals($cat1->getName(), $cats[0]->getName());
|
||||
|
||||
/* Adding the same category shouldn't change anything */
|
||||
$ret = $document->addCategories([$cat1]);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Check if category is used */
|
||||
$ret = $cat1->isUsed();
|
||||
$this->assertTrue($ret);
|
||||
$ret = $cat2->isUsed();
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* There is one document with cat 1 but none with cat 2 */
|
||||
$docs = $cat1->getDocumentsByCategory();
|
||||
$this->assertIsArray($docs);
|
||||
$this->assertCount(1, $docs);
|
||||
$num = $cat1->countDocumentsByCategory();
|
||||
$this->assertEquals(1, $num);
|
||||
$docs = $cat2->getDocumentsByCategory();
|
||||
$this->assertIsArray($docs);
|
||||
$this->assertCount(0, $docs);
|
||||
$num = $cat2->countDocumentsByCategory();
|
||||
$this->assertEquals(0, $num);
|
||||
|
||||
/* Still only one category */
|
||||
$cats = $document->getCategories();
|
||||
$this->assertIsArray($cats);
|
||||
$this->assertCount(1, $cats);
|
||||
|
||||
/* Setting new categories will replace the old ones */
|
||||
$ret = $document->setCategories([$cat1, $cat2]);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Now we have two categories */
|
||||
$cats = $document->getCategories();
|
||||
$this->assertIsArray($cats);
|
||||
$this->assertCount(2, $cats);
|
||||
|
||||
/* Remove a category */
|
||||
$ret = $document->removeCategories([$cat1]);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Removing the same category again does not harm*/
|
||||
$ret = $document->removeCategories([$cat1]);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* We are back to one category */
|
||||
$cats = $document->getCategories();
|
||||
$this->assertIsArray($cats);
|
||||
$this->assertCount(1, $cats);
|
||||
|
||||
/* Remove the remaining category from the document */
|
||||
$ret = $document->removeCategories($cats);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* No category left */
|
||||
$cats = $document->getCategories();
|
||||
$this->assertIsArray($cats);
|
||||
$this->assertCount(0, $cats);
|
||||
|
||||
/* Remove the category itself */
|
||||
$cats = self::$dms->getDocumentCategories();
|
||||
$this->assertIsArray($cats);
|
||||
$this->assertCount(2, $cats);
|
||||
$ret = $cat1->remove();
|
||||
$cats = self::$dms->getDocumentCategories();
|
||||
$this->assertIsArray($cats);
|
||||
$this->assertCount(1, $cats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getCategories() with sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetCategoriesSqlFail()
|
||||
{
|
||||
$document = $this->getMockedDocument();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT * FROM `tblCategory` WHERE"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($document->getCategories());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addCategories() with sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAddCategoriesSqlFail()
|
||||
{
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
/* mock sql statement in getCategories() which is called in addCategories() */
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT * FROM `tblCategory` WHERE"))
|
||||
->willReturn([]);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("INSERT INTO `tblDocumentCategory`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document = $this->getMockedDocument();
|
||||
$document->setDMS($dms);
|
||||
$cat = new SeedDMS_Core_DocumentCategory(1, 'Category');
|
||||
$cat->setDMS($dms);
|
||||
$this->assertFalse($document->addCategories([$cat]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method removeCategories() with sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRemoveCategoriesSqlFail()
|
||||
{
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("DELETE FROM `tblDocumentCategory` WHERE"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document = $this->getMockedDocument();
|
||||
$document->setDMS($dms);
|
||||
$cat = new SeedDMS_Core_DocumentCategory(1, 'Category');
|
||||
$cat->setDMS($dms);
|
||||
$this->assertFalse($document->removeCategories([$cat]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setCategories() with sql fail when deleting categories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetCategoriesSqlFail()
|
||||
{
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("DELETE FROM `tblDocumentCategory` WHERE"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document = $this->getMockedDocument();
|
||||
$document->setDMS($dms);
|
||||
$cat = new SeedDMS_Core_DocumentCategory(1, 'Category');
|
||||
$cat->setDMS($dms);
|
||||
$this->assertFalse($document->setCategories([$cat]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setCategories() with sql fail when inserting new categories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetCategoriesSqlFail2()
|
||||
{
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->exactly(2))
|
||||
->method('getResult')
|
||||
->will(
|
||||
$this->returnValueMap(
|
||||
array(
|
||||
array("DELETE FROM `tblDocumentCategory` WHERE `documentID` = 1", true, true),
|
||||
array("INSERT INTO `tblDocumentCategory`", true, false)
|
||||
)
|
||||
)
|
||||
);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document = $this->getMockedDocument();
|
||||
$document->setDMS($dms);
|
||||
$cat = new SeedDMS_Core_DocumentCategory(1, 'Category');
|
||||
$cat->setDMS($dms);
|
||||
$this->assertFalse($document->setCategories([$cat]));
|
||||
}
|
||||
|
||||
}
|
||||
|
593
SeedDMS_Core/tests/DocumentContentTest.php
Normal file
593
SeedDMS_Core/tests/DocumentContentTest.php
Normal file
|
@ -0,0 +1,593 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the document content tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* Group test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class DocumentContentTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getContent(), getContentByVersion(), getLatestContent()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetContent()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$version = $document->getContentByVersion(1);
|
||||
$this->assertIsObject($version);
|
||||
$this->assertEquals($version->getId(), $lcontent->getId());
|
||||
$content = $document->getContent();
|
||||
$this->assertIsArray($content);
|
||||
$this->assertCount(1, $content);
|
||||
$this->assertEquals($version->getId(), $content[0]->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getContent() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetContentSqlFail()
|
||||
{
|
||||
$document = $this->getMockedDocument();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT * FROM `tblDocumentContent` WHERE `document` "))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($document->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getContentByVersion() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetContentByVersionSqlFail()
|
||||
{
|
||||
$document = $this->getMockedDocument();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT * FROM `tblDocumentContent` WHERE `document` "))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($document->getContentByVersion(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getLatestContent() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetLatestContentSqlFail()
|
||||
{
|
||||
$document = $this->getMockedDocument();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT * FROM `tblDocumentContent` WHERE `document` "))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($document->getLatestContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method removeContent()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRemoveContent()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
|
||||
/* Removing the only version will fail */
|
||||
$ret = $document->removeContent($lcontent);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* Add a new version */
|
||||
$filename = self::createTempFile(300);
|
||||
$result = $document->addContent('', $user, $filename, 'file2.txt', '.txt', 'text/plain');
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($filename));
|
||||
$this->assertIsObject($result);
|
||||
$this->assertIsObject($result->getContent());
|
||||
|
||||
/* Second trial to remove a version. Now it succeeds because it is not
|
||||
* the last version anymore.
|
||||
*/
|
||||
$ret = $document->removeContent($lcontent);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* The latest version is now version 2 */
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$this->assertEquals(2, $lcontent->getVersion());
|
||||
|
||||
/* There is only 1 version left */
|
||||
$contents = $document->getContent();
|
||||
$this->assertIsArray($contents);
|
||||
$this->assertCount(1, $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method isType()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsType()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$ret = $lcontent->isType('documentcontent');
|
||||
$this->assertTrue($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getUser(), getDocument()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testVarious()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$ret = $lcontent->isType('documentcontent');
|
||||
$this->assertTrue($ret);
|
||||
$doc = $lcontent->getDocument();
|
||||
$this->assertEquals($document->getId(), $doc->getId());
|
||||
$u = $lcontent->getUser();
|
||||
$this->assertEquals($user->getId(), $u->getId());
|
||||
$filetype = $lcontent->getFileType();
|
||||
$this->assertEquals('.txt', $filetype);
|
||||
$origfilename = $lcontent->getOriginalFileName();
|
||||
$this->assertEquals('file1.txt', $origfilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getComment(), setComment()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetComment()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$comment = $lcontent->getComment();
|
||||
$this->assertEquals('', $comment);
|
||||
$ret = $lcontent->setComment('Document content comment');
|
||||
$this->assertTrue($ret);
|
||||
/* Retrieve the document content from the database again */
|
||||
$content = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$comment = $content->getComment();
|
||||
$this->assertEquals('Document content comment', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getDate(), setDate()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetDate()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$date = $lcontent->getDate();
|
||||
$this->assertIsInt($date);
|
||||
$this->assertGreaterThanOrEqual(time(), $date);
|
||||
|
||||
/* Set date as timestamp */
|
||||
$ret = $lcontent->setDate($date-1000);
|
||||
$this->assertTrue($ret);
|
||||
/* Retrieve the document content from the database again */
|
||||
$content = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$newdate = $content->getDate();
|
||||
$this->assertEquals($date-1000, $newdate);
|
||||
|
||||
/* Set date in Y-m-d H:i:s format */
|
||||
$date = time()-500;
|
||||
$ret = $lcontent->setDate(date('Y-m-d H:i:s', $date));
|
||||
$this->assertTrue($ret);
|
||||
/* Retrieve the document content from the database again */
|
||||
$content = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$newdate = $content->getDate();
|
||||
$this->assertEquals($date, $newdate);
|
||||
|
||||
/* Not passing a date will set the current date/time */
|
||||
$date = time();
|
||||
$ret = $lcontent->setDate();
|
||||
$this->assertTrue($ret);
|
||||
/* Retrieve the document content from the database again */
|
||||
$content = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$newdate = $content->getDate();
|
||||
$this->assertEquals($date, $newdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getFileSize(), setFileSize()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetFileSize()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1', 200);
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$filesize = $lcontent->getFileSize();
|
||||
$this->assertEquals(200, $filesize);
|
||||
|
||||
/* Intentially corrupt the file size */
|
||||
$db = self::$dms->getDb();
|
||||
$ret = $db->getResult("UPDATE `tblDocumentContent` SET `fileSize` = 300 WHERE `document` = " . $document->getID() . " AND `version` = " . $lcontent->getVersion());
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$corcontent = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$filesize = $corcontent->getFileSize();
|
||||
$this->assertEquals(300, $filesize);
|
||||
|
||||
/* Repair filesize by calling setFileSize() */
|
||||
$ret = $corcontent->setFileSize();
|
||||
$this->assertTrue($ret);
|
||||
$filesize = $corcontent->getFileSize();
|
||||
$this->assertEquals(200, $filesize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getChecksum(), setChecksum()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetChecksum()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1', 200);
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
$orgchecksum = $lcontent->getChecksum();
|
||||
$this->assertIsString($orgchecksum);
|
||||
$this->assertEquals(32, strlen($orgchecksum));
|
||||
|
||||
/* Intentially corrupt the checksum */
|
||||
$db = self::$dms->getDb();
|
||||
$ret = $db->getResult("UPDATE `tblDocumentContent` SET `checksum` = 'foobar' WHERE `document` = " . $document->getID() . " AND `version` = " . $lcontent->getVersion());
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$corcontent = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$checksum = $corcontent->getChecksum();
|
||||
$this->assertEquals('foobar', $checksum);
|
||||
|
||||
/* Repair filesize by calling setChecksum() */
|
||||
$ret = $corcontent->setChecksum();
|
||||
$this->assertTrue($ret);
|
||||
$checksum = $corcontent->getChecksum();
|
||||
$this->assertEquals($orgchecksum, $checksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getStatus(), setStatus(), getStatusLog()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetStatus()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1', 200);
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
|
||||
$status = $lcontent->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
$statuslog = $lcontent->getStatusLog();
|
||||
$this->assertIsArray($statuslog);
|
||||
$this->assertCount(1, $statuslog);
|
||||
|
||||
/* Missing update user returns false */
|
||||
$ret = $lcontent->setStatus(S_OBSOLETE, '', null);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* A status out of range returns false */
|
||||
$ret = $lcontent->setStatus(9, '', $user);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* A wrong date returns false */
|
||||
$ret = $lcontent->setStatus(S_OBSOLETE, '', $user, '2021-02-29 10:10:10');
|
||||
$this->assertFalse($ret);
|
||||
|
||||
$ret = $lcontent->setStatus(S_OBSOLETE, 'No longer valid', $user, date('Y-m-d H:i:s'));
|
||||
$status = $lcontent->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_OBSOLETE, $status['status']);
|
||||
|
||||
/* Status log has now 2 entries */
|
||||
$statuslog = $lcontent->getStatusLog();
|
||||
$this->assertIsArray($statuslog);
|
||||
$this->assertCount(2, $statuslog);
|
||||
|
||||
/* Add the 'onSetStatus' callback */
|
||||
$callret = '';
|
||||
$callback = function ($param, $content, $updateuser, $oldstatus, $newstatus) use (&$callret) {
|
||||
$callret = $oldstatus.' to '.$newstatus;
|
||||
return $param;
|
||||
};
|
||||
/* Because the callback will return false, the status will not be set */
|
||||
self::$dms->setCallback('onSetStatus', $callback, false);
|
||||
/* Trying to go back to status released with a callback returning false */
|
||||
$ret = $lcontent->setStatus(S_RELEASED, 'Valid again', $user);
|
||||
$status = $lcontent->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
/* Status is still S_OBSOLETE because the callback returned false */
|
||||
$this->assertEquals(S_OBSOLETE, $status['status']);
|
||||
$this->assertEquals(S_OBSOLETE.' to '.S_RELEASED, $callret);
|
||||
|
||||
/* Do it again, but this time the callback returns true */
|
||||
self::$dms->setCallback('onSetStatus', $callback, true);
|
||||
/* Trying to go back to status released with a callback returning true */
|
||||
$ret = $lcontent->setStatus(S_RELEASED, 'Valid again', $user);
|
||||
$status = $lcontent->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
/* Status updated to S_RELEASED because the callback returned true */
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
$this->assertEquals(S_OBSOLETE.' to '.S_RELEASED, $callret);
|
||||
|
||||
/* Status log has now 3 entries */
|
||||
$statuslog = $lcontent->getStatusLog();
|
||||
$this->assertIsArray($statuslog);
|
||||
$this->assertCount(3, $statuslog);
|
||||
|
||||
/* Get just the last entry */
|
||||
$statuslog = $lcontent->getStatusLog(1);
|
||||
$this->assertIsArray($statuslog);
|
||||
$this->assertCount(1, $statuslog);
|
||||
$this->assertEquals('Valid again', $statuslog[0]['comment']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getMimeType(), setMimeType()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetMimeType()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1', 200);
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
|
||||
$ret = $lcontent->setMimeType('text/csv');
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Retrieve the document content from the database again */
|
||||
$content = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$this->assertIsObject($content);
|
||||
$this->assertEquals('text/csv', $content->getMimeType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getFileType(), setFileType()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetFileType()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1', 200);
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
|
||||
$ret = $lcontent->setMimeType('text/css');
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$ret = $lcontent->setFileType();
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Retrieve the document content from the database again */
|
||||
$content = self::$dms->getDocumentContent($lcontent->getId());
|
||||
$this->assertIsObject($content);
|
||||
$this->assertEquals('.css', $content->getFileType());
|
||||
|
||||
/* Also get the file content to ensure the renaming of the file
|
||||
* on disc has succeeded.
|
||||
*/
|
||||
$c = file_get_contents(self::$dms->contentDir.$lcontent->getPath());
|
||||
$this->assertEquals(200, strlen($c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method replaceContent()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReplaceContent()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$guest = self::$dms->getUser(2);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1', 200);
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
|
||||
$filename = self::createTempFile(300);
|
||||
/* Not using the same user yields an error */
|
||||
$ret = $document->replaceContent(1, $guest, $filename, 'file1.txt', '.txt', 'text/plain');
|
||||
$this->assertFalse($ret);
|
||||
/* Not using the same orig. file name yields an error */
|
||||
$ret = $document->replaceContent(1, $user, $filename, 'file2.txt', '.txt', 'text/plain');
|
||||
$this->assertFalse($ret);
|
||||
/* Not using the same file type yields an error */
|
||||
$ret = $document->replaceContent(1, $user, $filename, 'file1.txt', '.csv', 'text/plain');
|
||||
$this->assertFalse($ret);
|
||||
/* Not using the same mime type yields an error */
|
||||
$ret = $document->replaceContent(1, $user, $filename, 'file1.txt', '.txt', 'text/csv');
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* Setting version to 0 will replace the latest version */
|
||||
$ret = $document->replaceContent(0, $user, $filename, 'file1.txt', '.txt', 'text/plain');
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($filename));
|
||||
|
||||
/* Retrieve the document content from the database again */
|
||||
$newcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($newcontent);
|
||||
$this->assertEquals('text/plain', $newcontent->getMimeType());
|
||||
/* File size has grown from 200 to 300 bytes */
|
||||
$filesize = $newcontent->getFileSize();
|
||||
$this->assertEquals(300, $filesize);
|
||||
/* Still version 1 */
|
||||
$version = $newcontent->getVersion();
|
||||
$this->assertEquals(1, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method replaceContent()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAccessMode()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$guest = self::$dms->getUser(2);
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1', 200);
|
||||
$this->assertIsObject($document);
|
||||
$lcontent = $document->getLatestContent();
|
||||
$this->assertIsObject($lcontent);
|
||||
|
||||
/* Access rights on a document content are always M_READ unless the callback
|
||||
* onCheckAccessDocumentContent is implemented */
|
||||
$mode = $lcontent->getAccessMode($user);
|
||||
$this->assertEquals(M_READ, $mode);
|
||||
}
|
||||
}
|
290
SeedDMS_Core/tests/DocumentFileTest.php
Normal file
290
SeedDMS_Core/tests/DocumentFileTest.php
Normal file
|
@ -0,0 +1,290 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the document file tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* Group test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class DocumentFileTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
self::$dbversion = self::$dms->getDBVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getInstance()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMockedDocumentFile()
|
||||
{
|
||||
$user = self::getMockedUser();
|
||||
$document1 = self::getMockedDocument(1, 'Document 1');
|
||||
$file = new SeedDMS_Core_DocumentFile(1, $document1, $user->getId(), 'comment', time(), '', '.txt', 'text/plain', 'test.txt', 'name', 1, true);
|
||||
$this->assertIsObject($file);
|
||||
$this->assertTrue($file->isType('documentfile'));
|
||||
|
||||
$document = $file->getDocument();
|
||||
$this->assertIsObject($document);
|
||||
$this->assertTrue($document->isType('document'));
|
||||
$this->assertEquals('Document 1', $document->getName());
|
||||
|
||||
$ispublic = $file->isPublic();
|
||||
$this->assertTrue($ispublic);
|
||||
|
||||
$comment = $file->getComment();
|
||||
$this->assertEquals('comment', $comment);
|
||||
|
||||
$filetype = $file->getFileType();
|
||||
$this->assertEquals('.txt', $filetype);
|
||||
|
||||
$mimetype = $file->getMimeType();
|
||||
$this->assertEquals('text/plain', $mimetype);
|
||||
|
||||
$name = $file->getName();
|
||||
$this->assertEquals('name', $name);
|
||||
|
||||
$origfilename = $file->getOriginalFileName();
|
||||
$this->assertEquals('test.txt', $origfilename);
|
||||
|
||||
$version = $file->getVersion();
|
||||
$this->assertEquals(1, $version);
|
||||
|
||||
$accessmode = $file->getAccessMode($user);
|
||||
$this->assertEquals(M_READ, $accessmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setComment() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetCommentSqlFail()
|
||||
{
|
||||
$user = self::getMockedUser();
|
||||
$document = $this->getMockedDocument();
|
||||
$file = new SeedDMS_Core_DocumentFile(1, $document, $user->getId(), 'comment', time(), '', '.txt', 'text/plain', 'test.txt', 'name', 1, true);
|
||||
$this->assertIsObject($file);
|
||||
$this->assertTrue($file->isType('documentfile'));
|
||||
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE `tblDocumentFiles` SET `comment`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($file->setComment('my comment'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setName() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetNameSqlFail()
|
||||
{
|
||||
$user = self::getMockedUser();
|
||||
$document = $this->getMockedDocument();
|
||||
$file = new SeedDMS_Core_DocumentFile(1, $document, $user->getId(), 'comment', time(), '', '.txt', 'text/plain', 'test.txt', 'name', 1, true);
|
||||
$this->assertIsObject($file);
|
||||
$this->assertTrue($file->isType('documentfile'));
|
||||
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE `tblDocumentFiles` SET `name`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($file->setName('my name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setDate() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetDateSqlFail()
|
||||
{
|
||||
$user = self::getMockedUser();
|
||||
$document = $this->getMockedDocument();
|
||||
$file = new SeedDMS_Core_DocumentFile(1, $document, $user->getId(), 'comment', time(), '', '.txt', 'text/plain', 'test.txt', 'name', 1, true);
|
||||
$this->assertIsObject($file);
|
||||
$this->assertTrue($file->isType('documentfile'));
|
||||
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE `tblDocumentFiles` SET `date`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($file->setDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setVersion() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetVersionSqlFail()
|
||||
{
|
||||
$user = self::getMockedUser();
|
||||
$document = $this->getMockedDocument();
|
||||
$file = new SeedDMS_Core_DocumentFile(1, $document, $user->getId(), 'comment', time(), '', '.txt', 'text/plain', 'test.txt', 'name', 1, true);
|
||||
$this->assertIsObject($file);
|
||||
$this->assertTrue($file->isType('documentfile'));
|
||||
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE `tblDocumentFiles` SET `version`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($file->setVersion(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setPublic() mit sql fail
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetPublicnSqlFail()
|
||||
{
|
||||
$user = self::getMockedUser();
|
||||
$document = $this->getMockedDocument();
|
||||
$file = new SeedDMS_Core_DocumentFile(1, $document, $user->getId(), 'comment', time(), '', '.txt', 'text/plain', 'test.txt', 'name', 1, true);
|
||||
$this->assertIsObject($file);
|
||||
$this->assertTrue($file->isType('documentfile'));
|
||||
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE `tblDocumentFiles` SET `public`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$document->setDMS($dms);
|
||||
$this->assertFalse($file->setPublic(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addDocumentFile(), getDocumentFile()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAddDocumentFile()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document);
|
||||
$tmpfile = self::createTempFile();
|
||||
$file = $document->addDocumentFile('attachment.txt', 'comment', $user, $tmpfile, 'attachment.txt', '.txt', 'text/plain', 0, true);
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($tmpfile));
|
||||
$this->assertIsObject($file);
|
||||
$this->assertTrue($file->isType('documentfile'));
|
||||
|
||||
$files = $document->getDocumentFiles();
|
||||
$this->assertIsArray($files);
|
||||
$this->assertCount(1, $files);
|
||||
|
||||
$file = $files[0];
|
||||
|
||||
$document = $file->getDocument();
|
||||
$this->assertIsObject($document);
|
||||
$this->assertTrue($document->isType('document'));
|
||||
$this->assertEquals('Document 1', $document->getName());
|
||||
|
||||
$ispublic = $file->isPublic();
|
||||
$this->assertTrue($ispublic);
|
||||
|
||||
$luser = $file->getUser();
|
||||
$this->assertIsObject($luser);
|
||||
$this->assertTrue($luser->isType('user'));
|
||||
|
||||
$ret = $file->setComment('new comment');
|
||||
$this->assertTrue($ret);
|
||||
$comment = $file->getComment();
|
||||
$this->assertEquals('new comment', $comment);
|
||||
|
||||
$ret = $file->setName('new name');
|
||||
$this->assertTrue($ret);
|
||||
$name = $file->getName();
|
||||
$this->assertEquals('new name', $name);
|
||||
|
||||
$now = time();
|
||||
$ret = $file->setDate($now);
|
||||
$this->assertTrue($ret);
|
||||
$date = $file->getDate();
|
||||
$this->assertEquals($now, $date);
|
||||
|
||||
$ret = $file->setDate('fail');
|
||||
$this->assertFalse($ret);
|
||||
|
||||
$ret = $file->setVersion(2);
|
||||
$this->assertTrue($ret);
|
||||
$version = $file->getVersion();
|
||||
$this->assertEquals(2, $version);
|
||||
|
||||
$ret = $file->setVersion('fail');
|
||||
$this->assertFalse($ret);
|
||||
|
||||
$ret = $file->setPublic(true);
|
||||
$this->assertTrue($ret);
|
||||
$ispublic = $file->isPublic();
|
||||
$this->assertEquals(1, $ispublic);
|
||||
|
||||
|
||||
}
|
||||
}
|
125
SeedDMS_Core/tests/DocumentLinkTest.php
Normal file
125
SeedDMS_Core/tests/DocumentLinkTest.php
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the document link tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* Group test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class DocumentLinkTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
self::$dbversion = self::$dms->getDBVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getInstance()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMockedDocumentLink()
|
||||
{
|
||||
$user = self::getMockedUser();
|
||||
$document1 = self::getMockedDocument(1, 'Document 1');
|
||||
$document2 = self::getMockedDocument(2, 'Document 2');
|
||||
$link = new SeedDMS_Core_DocumentLink(1, $document1, $document2, $user, true);
|
||||
$this->assertIsObject($link);
|
||||
$this->assertTrue($link->isType('documentlink'));
|
||||
|
||||
$document = $link->getDocument();
|
||||
$this->assertIsObject($document);
|
||||
$this->assertTrue($document->isType('document'));
|
||||
$this->assertEquals('Document 1', $document->getName());
|
||||
|
||||
$document = $link->getTarget();
|
||||
$this->assertIsObject($document);
|
||||
$this->assertTrue($document->isType('document'));
|
||||
$this->assertEquals('Document 2', $document->getName());
|
||||
|
||||
$ispublic = $link->isPublic();
|
||||
$this->assertTrue($ispublic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addDocumentLink(), getDocumentLink()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAddDocumentLink()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$document1 = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$this->assertIsObject($document1);
|
||||
$document2 = self::createDocument($rootfolder, $user, 'Document 2');
|
||||
$this->assertIsObject($document2);
|
||||
$link = $document1->addDocumentLink($document2->getId(), $user->getId(), true);
|
||||
$this->assertIsObject($link);
|
||||
$this->assertTrue($link->isType('documentlink'));
|
||||
|
||||
$document = $link->getDocument();
|
||||
$this->assertIsObject($document);
|
||||
$this->assertTrue($document->isType('document'));
|
||||
$this->assertEquals('Document 1', $document->getName());
|
||||
|
||||
$document = $link->getTarget();
|
||||
$this->assertIsObject($document);
|
||||
$this->assertTrue($document->isType('document'));
|
||||
$this->assertEquals('Document 2', $document->getName());
|
||||
|
||||
$ispublic = $link->isPublic();
|
||||
$this->assertTrue($ispublic);
|
||||
|
||||
$luser = $link->getUser();
|
||||
$this->assertIsObject($luser);
|
||||
$this->assertTrue($luser->isType('user'));
|
||||
}
|
||||
}
|
1323
SeedDMS_Core/tests/DocumentTest.php
Normal file
1323
SeedDMS_Core/tests/DocumentTest.php
Normal file
File diff suppressed because it is too large
Load Diff
219
SeedDMS_Core/tests/FileUtilsTest.php
Normal file
219
SeedDMS_Core/tests/FileUtilsTest.php
Normal file
|
@ -0,0 +1,219 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the file utils tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* Group test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class FileUtilsTest extends SeedDmsTest
|
||||
{
|
||||
/**
|
||||
* Create temporary directory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method format_filesize()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormatFileSize()
|
||||
{
|
||||
$this->assertEquals('1 Byte', SeedDMS_Core_File::format_filesize(1));
|
||||
$this->assertEquals('0 Bytes', SeedDMS_Core_File::format_filesize(0));
|
||||
$this->assertEquals('1000 Bytes', SeedDMS_Core_File::format_filesize(1000));
|
||||
$this->assertEquals('1 KiB', SeedDMS_Core_File::format_filesize(1024));
|
||||
$this->assertEquals('1 KiB', SeedDMS_Core_File::format_filesize(1025));
|
||||
$this->assertEquals('2 KiB', SeedDMS_Core_File::format_filesize(2047));
|
||||
$this->assertEquals('1 MiB', SeedDMS_Core_File::format_filesize(1024*1024));
|
||||
$this->assertEquals('1 GiB', SeedDMS_Core_File::format_filesize(1024*1024*1024));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method format_filesize()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testParseFileSize()
|
||||
{
|
||||
$this->assertEquals(200, SeedDMS_Core_File::parse_filesize('200B'));
|
||||
$this->assertEquals(200, SeedDMS_Core_File::parse_filesize('200 B'));
|
||||
$this->assertEquals(200, SeedDMS_Core_File::parse_filesize('200'));
|
||||
$this->assertEquals(1024, SeedDMS_Core_File::parse_filesize('1K'));
|
||||
$this->assertEquals(2*1024*1024, SeedDMS_Core_File::parse_filesize('2M'));
|
||||
$this->assertEquals(3*1024*1024*1024, SeedDMS_Core_File::parse_filesize('3 G'));
|
||||
$this->assertEquals(4*1024*1024*1024*1024, SeedDMS_Core_File::parse_filesize('4 T'));
|
||||
$this->assertFalse(SeedDMS_Core_File::parse_filesize('4 t'));
|
||||
$this->assertFalse(SeedDMS_Core_File::parse_filesize('-4T'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method fileSize()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFileSize()
|
||||
{
|
||||
$filename = self::createTempFile(200, self::$contentdir);
|
||||
$this->assertEquals(200, SeedDMS_Core_File::fileSize($filename));
|
||||
/* Getting the size of a none existing file returns false */
|
||||
$this->assertFalse(SeedDMS_Core_File::fileSize('foobar'));
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method file_exists()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFileExists()
|
||||
{
|
||||
$filename = self::createTempFile(200, self::$contentdir);
|
||||
$this->assertTrue(SeedDMS_Core_File::file_exists($filename));
|
||||
$this->assertFalse(SeedDMS_Core_File::file_exists($filename.'bla'));
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile($filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method fileExtension()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFileExtension()
|
||||
{
|
||||
$this->assertEquals('png', SeedDMS_Core_File::fileExtension('image/png'));
|
||||
$this->assertEquals('', SeedDMS_Core_File::fileExtension('image/kpng'));
|
||||
$this->assertEquals('txt', SeedDMS_Core_File::fileExtension('text/plain'));
|
||||
$this->assertEquals('md', SeedDMS_Core_File::fileExtension('text/markdown'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method moveFile()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMoveFile()
|
||||
{
|
||||
$filename = self::createTempFile(200, self::$contentdir);
|
||||
$this->assertEquals(200, SeedDMS_Core_File::fileSize($filename));
|
||||
$ret = SeedDMS_Core_File::moveFile($filename, self::$contentdir.DIRECTORY_SEPARATOR."foobar");
|
||||
$this->assertTrue($ret);
|
||||
/* Getting the file size of the old doc must fail now */
|
||||
$this->assertFalse(SeedDMS_Core_File::fileSize($filename));
|
||||
/* Getting the file size of the new doc succeds */
|
||||
$this->assertEquals(200, SeedDMS_Core_File::fileSize(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
$this->assertTrue(SeedDMS_Core_File::removeFile(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method makeDir(), renameDir(), removeDir()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMakeRenameAndRemoveDir()
|
||||
{
|
||||
/* Create a directory and put a file into it */
|
||||
$ret = SeedDMS_Core_File::makeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar");
|
||||
system('touch '.self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."tt");
|
||||
/* Rename the directory */
|
||||
$ret = SeedDMS_Core_File::renameDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar", self::$contentdir.DIRECTORY_SEPARATOR."bazfoo");
|
||||
$this->assertTrue($ret);
|
||||
/* The new must exist and the old one is gone */
|
||||
$this->assertTrue(is_dir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertFalse(is_dir(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
$this->assertTrue(SeedDMS_Core_File::removeDir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertFalse(SeedDMS_Core_File::removeDir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertFalse(SeedDMS_Core_File::removeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
|
||||
/* Create a directory, a sub directory and a file */
|
||||
$ret = SeedDMS_Core_File::makeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar");
|
||||
$this->assertTrue($ret);
|
||||
$ret = SeedDMS_Core_File::makeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."bazfoo");
|
||||
$this->assertTrue($ret);
|
||||
system('touch '.self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."bazfoo".DIRECTORY_SEPARATOR."tt");
|
||||
$this->assertTrue(SeedDMS_Core_File::file_exists(self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."bazfoo".DIRECTORY_SEPARATOR."tt"));
|
||||
|
||||
$ret = SeedDMS_Core_File::removeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar");
|
||||
$this->assertTrue($ret);
|
||||
$this->assertFalse(SeedDMS_Core_File::file_exists(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
$this->assertFalse(SeedDMS_Core_File::file_exists(self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertFalse(SeedDMS_Core_File::file_exists(self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."bazfoo".DIRECTORY_SEPARATOR."tt"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method makeDir(), copyDir(), removeDir()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMakeCopyAndRemoveDir()
|
||||
{
|
||||
/* Create a directory and put a file into it */
|
||||
$ret = SeedDMS_Core_File::makeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar");
|
||||
system('touch '.self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."tt");
|
||||
/* Rename the directory */
|
||||
$ret = SeedDMS_Core_File::copyDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar", self::$contentdir.DIRECTORY_SEPARATOR."bazfoo");
|
||||
$this->assertTrue($ret);
|
||||
/* The new and the old dir must exist */
|
||||
$this->assertTrue(is_dir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertTrue(is_dir(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
$this->assertTrue(SeedDMS_Core_File::removeDir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertTrue(SeedDMS_Core_File::removeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method moveDir()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMakeAndMoveDir()
|
||||
{
|
||||
/* Create a directory and put a file into it */
|
||||
$ret = SeedDMS_Core_File::makeDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar");
|
||||
system('touch '.self::$contentdir.DIRECTORY_SEPARATOR."foobar".DIRECTORY_SEPARATOR."tt");
|
||||
/* Rename the directory */
|
||||
$ret = SeedDMS_Core_File::moveDir(self::$contentdir.DIRECTORY_SEPARATOR."foobar", self::$contentdir.DIRECTORY_SEPARATOR."bazfoo");
|
||||
$this->assertTrue($ret);
|
||||
/* The new must exist and the old dir must be disappeared */
|
||||
$this->assertTrue(is_dir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertFalse(is_dir(self::$contentdir.DIRECTORY_SEPARATOR."foobar"));
|
||||
$this->assertTrue(SeedDMS_Core_File::removeDir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
$this->assertFalse(is_dir(self::$contentdir.DIRECTORY_SEPARATOR."bazfoo"));
|
||||
}
|
||||
}
|
1221
SeedDMS_Core/tests/FolderTest.php
Normal file
1221
SeedDMS_Core/tests/FolderTest.php
Normal file
File diff suppressed because it is too large
Load Diff
410
SeedDMS_Core/tests/GroupTest.php
Normal file
410
SeedDMS_Core/tests/GroupTest.php
Normal file
|
@ -0,0 +1,410 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the group tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* Group test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class GroupTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
self::$dbversion = self::$dms->getDBVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock group object
|
||||
*
|
||||
* @return SeedDMS_Core_Group
|
||||
*/
|
||||
protected function getMockGroup()
|
||||
{
|
||||
$user = $this->getMockBuilder(SeedDMS_Core_Group::class)
|
||||
->onlyMethods([])
|
||||
->disableOriginalConstructor()->getMock();
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock group object
|
||||
*
|
||||
* @return SeedDMS_Core_Group
|
||||
*/
|
||||
protected function getGroup()
|
||||
{
|
||||
$group = new SeedDMS_Core_Group(1, 'foogroup', 'My comment');
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock regular user object
|
||||
*
|
||||
* @return SeedDMS_Core_User
|
||||
*/
|
||||
protected function getUser()
|
||||
{
|
||||
$user = new SeedDMS_Core_User(2, 'user', 'pass', 'Joe Baz', 'joe@foo.de', 'en_GB', 'bootstrap', 'My comment', SeedDMS_Core_User::role_user);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method isType()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsType()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$this->assertTrue($group->isType('group'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getName()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetName()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$this->assertEquals('foogroup', $group->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getName() and setName()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetName()
|
||||
{
|
||||
$group = self::$dms->addGroup('Group', '');
|
||||
$ret = $group->setName('foo');
|
||||
$this->assertTrue($ret);
|
||||
$name = $group->getName();
|
||||
$this->assertEquals('foo', $name);
|
||||
/* Setting an empty name must fail */
|
||||
$ret = $group->setName(' ');
|
||||
$this->assertFalse($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setName()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetNameSqlFail()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE `tblGroups` SET `name`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$group->setDMS($dms);
|
||||
$this->assertFalse($group->setName('my name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getComment()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetComment()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$this->assertEquals('My comment', $group->getComment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getComment() and setComment()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetComment()
|
||||
{
|
||||
$group = self::$dms->addGroup('Group', '');
|
||||
$ret = $group->setComment('foo');
|
||||
$this->assertTrue($ret);
|
||||
$comment = $group->getComment();
|
||||
$this->assertEquals('foo', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setComment()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetCommentSqlFail()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResult')
|
||||
->with($this->stringContains("UPDATE `tblGroups` SET `comment`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$group->setDMS($dms);
|
||||
$this->assertFalse($group->setComment('my comment'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getUsers()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetUsersSqlFail()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("SELECT `tblUsers`.* FROM `tblUsers`"))
|
||||
->willReturn(false);
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$group->setDMS($dms);
|
||||
$this->assertFalse($group->getUsers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addUser(), isMember(), and removeUser()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAddAndRemoveUser()
|
||||
{
|
||||
$group = self::$dms->addGroup('Group', '');
|
||||
if(self::$dms->version[0] == '5')
|
||||
$role = SeedDMS_Core_User::role_user;
|
||||
else {
|
||||
$role = SeedDMS_Core_Role::getInstance(3, self::$dms);
|
||||
$this->assertIsObject($role);
|
||||
$this->assertEquals($role->getRole(), SeedDMS_Core_Role::role_user);
|
||||
}
|
||||
$user1 = self::$dms->addUser('joe', 'pass', 'Joe Foo', 'joe@foo.de', 'en_GB', 'bootstrap', 'My comment', $role);
|
||||
$user2 = self::$dms->addUser('sally', 'pass', 'Sally Foo', 'sally@foo.de', 'en_GB', 'bootstrap', 'My comment', $role);
|
||||
|
||||
/* Add user1 and user2. user2 is also a manager */
|
||||
$ret = $group->addUser($user1);
|
||||
$this->assertTrue($ret);
|
||||
$ret = $group->addUser($user2, true);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$users = $group->getUsers();
|
||||
$this->assertIsArray($users);
|
||||
$this->assertCount(2, $users);
|
||||
|
||||
$ret = $group->removeUser($user1);
|
||||
$this->assertTrue($ret);
|
||||
$users = $group->getUsers();
|
||||
$this->assertIsArray($users);
|
||||
$this->assertCount(1, $users);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method isMember(), toggleManager()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsMember()
|
||||
{
|
||||
$group = self::$dms->addGroup('Group', '');
|
||||
$user1 = self::$dms->addUser('joe', 'pass', 'Joe Foo', 'joe@foo.de', 'en_GB', 'bootstrap', 'My comment');
|
||||
$user2 = self::$dms->addUser('sally', 'pass', 'Sally Foo', 'sally@foo.de', 'en_GB', 'bootstrap', 'My comment');
|
||||
|
||||
/* Add user1 and user2. user2 is also a manager */
|
||||
$ret = $group->addUser($user1);
|
||||
$this->assertTrue($ret);
|
||||
$ret = $group->addUser($user2, true);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* user1 is a member but not a manager */
|
||||
$ret = $group->isMember($user1);
|
||||
$this->assertTrue($ret);
|
||||
$ret = $group->isMember($user1, true);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* user2 is a member and a manager */
|
||||
$ret = $group->isMember($user2, true);
|
||||
$this->assertTrue($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method toggleManager()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToggleManager()
|
||||
{
|
||||
$group = self::$dms->addGroup('Group', '');
|
||||
$user1 = self::$dms->addUser('joe', 'pass', 'Joe Foo', 'joe@foo.de', 'en_GB', 'bootstrap', 'My comment');
|
||||
|
||||
/* Add user1 */
|
||||
$ret = $group->addUser($user1);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* user1 is a member but not a manager */
|
||||
$ret = $group->isMember($user1);
|
||||
$this->assertTrue($ret);
|
||||
$ret = $group->isMember($user1, true);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* Toggle manager mode of user 1 and check again */
|
||||
$ret = $group->toggleManager($user1);
|
||||
$ret = $group->isMember($user1, true);
|
||||
$this->assertTrue($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getUsers()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetUsers()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
if(self::$dbversion['major'] == 6) {
|
||||
$db->expects($this->exactly(2))
|
||||
->method('getResultArray')
|
||||
->withConsecutive([$this->stringContains("`tblGroupMembers`.`groupID` = '".$group->getId()."'")], [$this->stringContains("SELECT * FROM `tblRoles` WHERE `id` =")])
|
||||
->willReturnOnConsecutiveCalls(array(array('id'=>2, 'login'=>'user', 'pwd'=>'pass', 'fullName'=>'Joe Baz', 'email'=>'joe@foo.de', 'language'=>'en_GB', 'theme'=>'bootstrap', 'comment'=>'', 'role'=>SeedDMS_Core_User::role_user, 'hidden'=>0, 'role'=>1)), array('id'=>1, 'name'=>'role', 'role'=>1, 'noaccess'=>''));
|
||||
} else {
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("`tblGroupMembers`.`groupID` = '".$group->getId()."'"))
|
||||
->willReturn(array(array('id'=>2, 'login'=>'user', 'pwd'=>'pass', 'fullName'=>'Joe Baz', 'email'=>'joe@foo.de', 'language'=>'en_GB', 'theme'=>'bootstrap', 'comment'=>'', 'role'=>SeedDMS_Core_User::role_user, 'hidden'=>0, 'role'=>1)));
|
||||
}
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
|
||||
$group->setDMS($dms);
|
||||
$users = $group->getUsers();
|
||||
$this->assertIsArray($users);
|
||||
$this->assertCount(1, $users);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getManagers()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetManagers()
|
||||
{
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
if(self::$dbversion['major'] == 6) {
|
||||
$db->expects($this->exactly(2))
|
||||
->method('getResultArray')
|
||||
->withConsecutive([$this->stringContains("`manager` = 1")], [$this->stringContains("SELECT * FROM `tblRoles` WHERE `id` =")])
|
||||
->willReturnOnConsecutiveCalls(array(array('id'=>2, 'login'=>'user', 'pwd'=>'pass', 'fullName'=>'Joe Baz', 'email'=>'joe@foo.de', 'language'=>'en_GB', 'theme'=>'bootstrap', 'comment'=>'', 'role'=>SeedDMS_Core_User::role_user, 'hidden'=>0, 'role'=>1)), array('id'=>1, 'name'=>'role', 'role'=>1, 'noaccess'=>''));
|
||||
} else {
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains('`manager` = 1'))
|
||||
->willReturn(array(array('id'=>2, 'login'=>'user', 'pwd'=>'pass', 'fullName'=>'Joe Baz', 'email'=>'joe@foo.de', 'language'=>'en_GB', 'theme'=>'bootstrap', 'comment'=>'', 'role'=>SeedDMS_Core_User::role_user, 'hidden'=>0)));
|
||||
}
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
|
||||
$group = $this->getGroup();
|
||||
$group->setDMS($dms);
|
||||
$managers = $group->getManagers();
|
||||
$this->assertIsArray($managers);
|
||||
$this->assertCount(1, $managers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getNotifications()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetNotifications()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("WHERE `tblNotify`.`groupID` = ".$group->getId()))
|
||||
->willReturn(array(array('target'=>2, 'targetType'=>'0', 'userID'=>0, 'groupID'=>$group->getId())));
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$group->setDMS($dms);
|
||||
$notifications = $group->getNotifications();
|
||||
$this->assertIsArray($notifications);
|
||||
$this->assertCount(1, $notifications);
|
||||
$this->assertInstanceOf(SeedDMS_Core_Notification::class, $notifications[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getNotifications() with target type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetNotificationsWithTargetType()
|
||||
{
|
||||
$group = $this->getGroup();
|
||||
$db = $this->createMock(SeedDMS_Core_DatabaseAccess::class);
|
||||
$db->expects($this->once())
|
||||
->method('getResultArray')
|
||||
->with($this->stringContains("WHERE `tblNotify`.`groupID` = ".$group->getId()." AND `tblNotify`.`targetType` = 1"))
|
||||
->willReturn(array(array('target'=>2, 'targetType'=>'1', 'userID'=>0, 'groupID'=>$group->getId())));
|
||||
$dms = new SeedDMS_Core_DMS($db, '');
|
||||
$group->setDMS($dms);
|
||||
$notifications = $group->getNotifications(1);
|
||||
$this->assertIsArray($notifications);
|
||||
$this->assertCount(1, $notifications);
|
||||
$this->assertInstanceOf(SeedDMS_Core_Notification::class, $notifications[0]);
|
||||
}
|
||||
|
||||
|
||||
}
|
147
SeedDMS_Core/tests/KeywordCategoryTest.php
Normal file
147
SeedDMS_Core/tests/KeywordCategoryTest.php
Normal file
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the keyword tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* User test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class KeywordCategoryTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getName() and setName()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetName()
|
||||
{
|
||||
$user = SeedDMS_Core_User::getInstance(1, self::$dms);
|
||||
$cat = self::$dms->addKeywordCategory($user->getId(), 'Category 1');
|
||||
$name = $cat->getName();
|
||||
$ret = $cat->setName('foo');
|
||||
$this->assertTrue($ret);
|
||||
$name = $cat->getName();
|
||||
$this->assertEquals('foo', $name);
|
||||
$ret = $cat->setName(' ');
|
||||
$this->assertFalse($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getOwner() and setOwner()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetOwner()
|
||||
{
|
||||
$user = SeedDMS_Core_User::getInstance(1, self::$dms);
|
||||
$guest = SeedDMS_Core_User::getInstance(2, self::$dms);
|
||||
$cat = self::$dms->addKeywordCategory($user->getId(), 'Category 1');
|
||||
$this->assertIsObject($cat);
|
||||
$ret = $cat->setOwner($guest);
|
||||
$this->assertTrue($ret);
|
||||
$owner = $cat->getOwner();
|
||||
$this->assertEquals(2, $owner->getId());
|
||||
$ret = $cat->setOwner(null);
|
||||
$this->assertFalse($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addKeywordList() and editKeywordList(), getKeywordLists(), removeKeywordList()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetSetEditAndRemoveKeywordList()
|
||||
{
|
||||
$user = SeedDMS_Core_User::getInstance(1, self::$dms);
|
||||
$cat = self::$dms->addKeywordCategory($user->getId(), 'Category 1');
|
||||
$this->assertIsObject($cat);
|
||||
$ret = $cat->addKeywordList('foo');
|
||||
$this->assertTrue($ret);
|
||||
$ret = $cat->addKeywordList('bar');
|
||||
$this->assertTrue($ret);
|
||||
$list = $cat->getKeywordLists();
|
||||
$this->assertIsArray($list);
|
||||
$this->assertCount(2, $list);
|
||||
$ret = $cat->editKeywordList(1, 'baz');
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$ret = $cat->removeKeywordList(1);
|
||||
$this->assertTrue($ret);
|
||||
$list = $cat->getKeywordLists();
|
||||
$this->assertIsArray($list);
|
||||
$this->assertCount(1, $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addKeywordCategory() and remove()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAndAndRemoveKeywordCategory()
|
||||
{
|
||||
$user = SeedDMS_Core_User::getInstance(1, self::$dms);
|
||||
$cat = self::$dms->addKeywordCategory($user->getId(), 'Category 1');
|
||||
$this->assertIsObject($cat);
|
||||
$ret = $cat->addKeywordList('foo');
|
||||
$this->assertTrue($ret);
|
||||
$ret = $cat->addKeywordList('bar');
|
||||
$this->assertTrue($ret);
|
||||
$ret = $cat->remove();
|
||||
$this->assertTrue($ret);
|
||||
}
|
||||
}
|
477
SeedDMS_Core/tests/ReviewApprovalTest.php
Normal file
477
SeedDMS_Core/tests/ReviewApprovalTest.php
Normal file
|
@ -0,0 +1,477 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the review and approval tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* Group test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class ReviewApprovalTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addIndReviewer(), addGrpReviewer(), verifyStatus(),
|
||||
* getReviewStatus(), removeReview(), delIndReviewer()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReviewDocumentByUserAndGroup()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertIsObject($user);
|
||||
|
||||
/* Add a new user who will be the reviewer */
|
||||
$reviewer = self::$dms->addUser('reviewer', 'reviewer', 'Reviewer One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($reviewer);
|
||||
|
||||
/* Add a new group which will be the reviewer */
|
||||
$reviewergrp = self::$dms->addGroup('reviewer', '');
|
||||
$this->assertIsObject($reviewergrp);
|
||||
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$content = $document->getLatestContent();
|
||||
$this->assertIsObject($content);
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
/* A missing reviewer or user causes an error */
|
||||
$ret = $content->addIndReviewer($reviewer, null);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* A missing reviewer or user causes an error */
|
||||
$ret = $content->addIndReviewer(null, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a group instead of a user causes an error */
|
||||
$ret = $content->addIndReviewer($reviewergrp, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Finally add the reviewer */
|
||||
$ret = $content->addIndReviewer($reviewer, $user);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
|
||||
/* Adding the user again will yield in an error */
|
||||
$ret = $content->addIndReviewer($reviewer, $user);
|
||||
$this->assertEquals(-3, $ret);
|
||||
|
||||
/* Needs to call verifyStatus() in order to recalc the status */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_DRAFT_REV, $newstatus);
|
||||
|
||||
/* Get all reviews */
|
||||
$reviewstatus = $content->getReviewStatus();
|
||||
$this->assertIsArray($reviewstatus);
|
||||
$this->assertCount(1, $reviewstatus);
|
||||
|
||||
/* Get list of individual und group reviewers */
|
||||
$reviewers = $content->getReviewers();
|
||||
$this->assertIsArray($reviewers);
|
||||
$this->assertCount(2, $reviewers);
|
||||
$this->assertCount(1, $reviewers['i']);
|
||||
$this->assertCount(0, $reviewers['g']);
|
||||
/*
|
||||
$db = self::$dms->getDB();
|
||||
$db->createTemporaryTable("ttreviewid", true);
|
||||
$queryStr = "SELECT * FROM ttreviewid";
|
||||
$recs = $db->getResultArray($queryStr);
|
||||
echo $db->getErrorMsg();
|
||||
var_dump($recs);
|
||||
*/
|
||||
|
||||
/* A missing reviewer or user causes an error */
|
||||
$ret = $content->addGrpReviewer($reviewergrp, null);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* A missing reviewer or user causes an error */
|
||||
$ret = $content->addGrpReviewer(null, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a user instead of a group causes an error */
|
||||
$ret = $content->addGrpReviewer($reviewer, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Finally add the reviewer */
|
||||
$ret = $content->addGrpReviewer($reviewergrp, $user);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
$groupstatus = $reviewergrp->getReviewStatus();
|
||||
|
||||
/* Adding the group again will yield in an error */
|
||||
$ret = $content->addGrpReviewer($reviewergrp, $user);
|
||||
$this->assertEquals(-3, $ret);
|
||||
|
||||
/* Get all reviews */
|
||||
$reviewstatus = $content->getReviewStatus();
|
||||
$this->assertIsArray($reviewstatus);
|
||||
$this->assertCount(2, $reviewstatus);
|
||||
|
||||
/* Get list of individual und group reviewers */
|
||||
$reviewers = $content->getReviewers();
|
||||
$this->assertIsArray($reviewers);
|
||||
$this->assertCount(2, $reviewers);
|
||||
$this->assertCount(1, $reviewers['i']);
|
||||
$this->assertCount(1, $reviewers['g']);
|
||||
|
||||
$userstatus = $reviewer->getReviewStatus();
|
||||
$groupstatus = $reviewergrp->getReviewStatus();
|
||||
|
||||
/* There should be two log entries, one for each reviewer */
|
||||
$reviewlog = $content->getReviewLog(5);
|
||||
$this->assertIsArray($reviewlog);
|
||||
$this->assertCount(2, $reviewlog);
|
||||
|
||||
/* Adding a review without a user of reviewer causes an error */
|
||||
$ret = $content->setReviewByInd($reviewer, null, S_LOG_ACCEPTED, 'Comment of individual reviewer');
|
||||
$this->assertEquals(-1, $ret);
|
||||
$ret = $content->setReviewByInd(null, $user, S_LOG_ACCEPTED, 'Comment of individual reviewer');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a review as an individual but passing a group causes an error */
|
||||
$ret = $content->setReviewByInd($reviewergrp, $user, S_LOG_ACCEPTED, 'Comment of individual reviewer');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Individual reviewer reviews document */
|
||||
$ret = $content->setReviewByInd($reviewer, $user, S_LOG_ACCEPTED, 'Comment of individual reviewer');
|
||||
$this->assertIsInt(0, $ret);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
|
||||
/* Get the last 5 review log entries (actually there are just 3 now) */
|
||||
$reviewlog = $content->getReviewLog(5);
|
||||
$this->assertIsArray($reviewlog);
|
||||
$this->assertCount(3, $reviewlog);
|
||||
$this->assertEquals('Comment of individual reviewer', $reviewlog[0]['comment']);
|
||||
$this->assertEquals(1, $reviewlog[0]['status']);
|
||||
|
||||
/* Needs to call verifyStatus() in order to recalc the status.
|
||||
* It must not be changed because the group reviewer has not done the
|
||||
* review.
|
||||
*/
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_DRAFT_REV, $newstatus);
|
||||
|
||||
/* Adding a review without a user of reviewer causes an error */
|
||||
$ret = $content->setReviewByGrp($reviewergrp, null, S_LOG_ACCEPTED, 'Comment of group reviewer');
|
||||
$this->assertEquals(-1, $ret);
|
||||
$ret = $content->setReviewByGrp(null, $user, S_LOG_ACCEPTED, 'Comment of group reviewer');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a review as an group but passing a user causes an error */
|
||||
$ret = $content->setReviewByGrp($reviewer, $user, S_LOG_ACCEPTED, 'Comment of group reviewer');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Group reviewer reviews document */
|
||||
$ret = $content->setReviewByGrp($reviewergrp, $user, S_LOG_ACCEPTED, 'Comment of group reviewer');
|
||||
$this->assertIsInt(0, $ret);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
|
||||
/* Get the last 5 review log entries (actually there are just 4 now) */
|
||||
$reviewlog = $content->getReviewLog(5);
|
||||
$this->assertIsArray($reviewlog);
|
||||
$this->assertCount(4, $reviewlog);
|
||||
$this->assertEquals('Comment of group reviewer', $reviewlog[0]['comment']);
|
||||
$this->assertEquals(1, $reviewlog[0]['status']);
|
||||
|
||||
/* Now the document has received all reviews */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_RELEASED, $newstatus);
|
||||
|
||||
/* Remove the last review of the user */
|
||||
$userstatus = $reviewer->getReviewStatus($document->getId(), $content->getVersion());
|
||||
$this->assertIsArray($userstatus);
|
||||
$this->assertCount(2, $userstatus);
|
||||
$this->assertCount(1, $userstatus['indstatus']);
|
||||
$ret = $content->removeReview($userstatus['indstatus'][$document->getId()]['reviewID'], $user, 'Undo review');
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Get the last 8 review log entries (actually there are just 5 now) */
|
||||
$reviewlog = $content->getReviewLog(8);
|
||||
$this->assertIsArray($reviewlog);
|
||||
$this->assertCount(5, $reviewlog);
|
||||
$this->assertEquals('Undo review', $reviewlog[0]['comment']);
|
||||
$this->assertEquals(0, $reviewlog[0]['status']);
|
||||
|
||||
/* Now the document must be back in draft mode */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_DRAFT_REV, $newstatus);
|
||||
|
||||
/* Removing the user as a reviewer completly will release the
|
||||
* document again, because the group reviewer became the only
|
||||
* reviewer and has done the review already.
|
||||
*/
|
||||
$ret = $content->delIndReviewer($reviewer, $user, 'Reviewer removed');
|
||||
$this->assertIsInt($ret);
|
||||
$this->assertEquals(0, $ret);
|
||||
|
||||
/* Get the last 8 review log entries (actually there are just 6 now) */
|
||||
$reviewlog = $content->getReviewLog(8);
|
||||
$this->assertIsArray($reviewlog);
|
||||
$this->assertCount(6, $reviewlog);
|
||||
$this->assertEquals('Reviewer removed', $reviewlog[0]['comment']);
|
||||
$this->assertEquals(-2, $reviewlog[0]['status']);
|
||||
|
||||
/* Now the document will be released again */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_RELEASED, $newstatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method addIndApprover(), addGrpApprover(), verifyStatus(),
|
||||
* getApprovalStatus(), removeApproval(), delIndApprover()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testApproveDocumentByUserAndGroup()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertIsObject($user);
|
||||
|
||||
/* Add a new user who will be the approver */
|
||||
$approver = self::$dms->addUser('approver', 'approver', 'Approver One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($approver);
|
||||
|
||||
/* Add a new group which will be the approver */
|
||||
$approvergrp = self::$dms->addGroup('approver', '');
|
||||
$this->assertIsObject($approvergrp);
|
||||
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$content = $document->getLatestContent();
|
||||
$this->assertIsObject($content);
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
/* A missing approver or user causes an error */
|
||||
$ret = $content->addIndApprover($approver, null);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* A missing approver or user causes an error */
|
||||
$ret = $content->addIndApprover(null, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a group instead of a user causes an error */
|
||||
$ret = $content->addIndApprover($approvergrp, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Finally add the reviewer */
|
||||
$ret = $content->addIndApprover($approver, $user);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
|
||||
/* Adding the user again will yield in an error */
|
||||
$ret = $content->addIndApprover($approver, $user);
|
||||
$this->assertEquals(-3, $ret);
|
||||
|
||||
/* Needs to call verifyStatus() in order to recalc the status */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_DRAFT_APP, $newstatus);
|
||||
|
||||
/* Get all approvals */
|
||||
$approvalstatus = $content->getApprovalStatus();
|
||||
$this->assertIsArray($approvalstatus);
|
||||
$this->assertCount(1, $approvalstatus);
|
||||
|
||||
/* Get list of individual und group approvers */
|
||||
$approvers = $content->getApprovers();
|
||||
$this->assertIsArray($approvers);
|
||||
$this->assertCount(2, $approvers);
|
||||
$this->assertCount(1, $approvers['i']);
|
||||
$this->assertCount(0, $approvers['g']);
|
||||
|
||||
/* A missing approver or user causes an error */
|
||||
$ret = $content->addGrpApprover($approvergrp, null);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* A missing approver or user causes an error */
|
||||
$ret = $content->addGrpApprover(null, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a user instead of a group causes an error */
|
||||
$ret = $content->addGrpApprover($approver, $user);
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Finally add the reviewer */
|
||||
$ret = $content->addGrpApprover($approvergrp, $user);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
$groupstatus = $approvergrp->getApprovalStatus();
|
||||
|
||||
/* Adding the group again will yield in an error */
|
||||
$ret = $content->addGrpApprover($approvergrp, $user);
|
||||
$this->assertEquals(-3, $ret);
|
||||
|
||||
/* Get all approvals */
|
||||
$approvalstatus = $content->getApprovalStatus();
|
||||
$this->assertIsArray($approvalstatus);
|
||||
$this->assertCount(2, $approvalstatus);
|
||||
|
||||
/* Get list of individual und group approvers */
|
||||
$approvers = $content->getApprovers();
|
||||
$this->assertIsArray($approvers);
|
||||
$this->assertCount(2, $approvers);
|
||||
$this->assertCount(1, $approvers['i']);
|
||||
$this->assertCount(1, $approvers['g']);
|
||||
|
||||
$userstatus = $approver->getApprovalStatus();
|
||||
$groupstatus = $approvergrp->getApprovalStatus();
|
||||
|
||||
/* There should be two log entries, one for each approver */
|
||||
$approvallog = $content->getApproveLog(5);
|
||||
$this->assertIsArray($approvallog);
|
||||
$this->assertCount(2, $approvallog);
|
||||
|
||||
/* Adding a approval without a user of approver causes an error */
|
||||
$ret = $content->setApprovalByInd($approver, null, S_LOG_ACCEPTED, 'Comment of individual approver');
|
||||
$this->assertEquals(-1, $ret);
|
||||
$ret = $content->setApprovalByInd(null, $user, S_LOG_ACCEPTED, 'Comment of individual approver');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a approval as an individual but passing a group causes an error */
|
||||
$ret = $content->setApprovalByInd($approvergrp, $user, S_LOG_ACCEPTED, 'Comment of individual approver');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Individual approver approvals document */
|
||||
$ret = $content->setApprovalByInd($approver, $user, S_LOG_ACCEPTED, 'Comment of individual approver');
|
||||
$this->assertIsInt(0, $ret);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
|
||||
/* Get the last 5 approval log entries (actually there are just 3 now) */
|
||||
$approvallog = $content->getApproveLog(5);
|
||||
$this->assertIsArray($approvallog);
|
||||
$this->assertCount(3, $approvallog);
|
||||
$this->assertEquals('Comment of individual approver', $approvallog[0]['comment']);
|
||||
$this->assertEquals(1, $approvallog[0]['status']);
|
||||
|
||||
/* Needs to call verifyStatus() in order to recalc the status.
|
||||
* It must not be changed because the group approver has not done the
|
||||
* approval.
|
||||
*/
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_DRAFT_APP, $newstatus);
|
||||
|
||||
/* Adding a approval without a user of approver causes an error */
|
||||
$ret = $content->setApprovalByGrp($approvergrp, null, S_LOG_ACCEPTED, 'Comment of group approver');
|
||||
$this->assertEquals(-1, $ret);
|
||||
$ret = $content->setApprovalByGrp(null, $user, S_LOG_ACCEPTED, 'Comment of group approver');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Adding a approval as an group but passing a user causes an error */
|
||||
$ret = $content->setApprovalByGrp($approver, $user, S_LOG_ACCEPTED, 'Comment of group approver');
|
||||
$this->assertEquals(-1, $ret);
|
||||
|
||||
/* Group approver approvals document */
|
||||
$ret = $content->setApprovalByGrp($approvergrp, $user, S_LOG_ACCEPTED, 'Comment of group approver');
|
||||
$this->assertIsInt(0, $ret);
|
||||
$this->assertGreaterThan(0, $ret);
|
||||
|
||||
/* Get the last 5 approval log entries (actually there are just 4 now) */
|
||||
$approvallog = $content->getApproveLog(5);
|
||||
$this->assertIsArray($approvallog);
|
||||
$this->assertCount(4, $approvallog);
|
||||
$this->assertEquals('Comment of group approver', $approvallog[0]['comment']);
|
||||
$this->assertEquals(1, $approvallog[0]['status']);
|
||||
|
||||
/* Now the document has received all approvals */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_RELEASED, $newstatus);
|
||||
|
||||
/* Remove the last approval of the user */
|
||||
$userstatus = $approver->getApprovalStatus($document->getId(), $content->getVersion());
|
||||
$this->assertIsArray($userstatus);
|
||||
$this->assertCount(2, $userstatus);
|
||||
$this->assertCount(1, $userstatus['indstatus']);
|
||||
$ret = $content->removeApproval($userstatus['indstatus'][$document->getId()]['approveID'], $user, 'Undo approval');
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Get the last 8 approval log entries (actually there are just 5 now) */
|
||||
$approvallog = $content->getApproveLog(8);
|
||||
$this->assertIsArray($approvallog);
|
||||
$this->assertCount(5, $approvallog);
|
||||
$this->assertEquals('Undo approval', $approvallog[0]['comment']);
|
||||
$this->assertEquals(0, $approvallog[0]['status']);
|
||||
|
||||
/* Now the document must be back in draft mode */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_DRAFT_APP, $newstatus);
|
||||
|
||||
/* Removing the user as a approver completly will release the
|
||||
* document again, because the group approver became the only
|
||||
* approver and has done the approval already.
|
||||
*/
|
||||
$ret = $content->delIndApprover($approver, $user, 'Approver removed');
|
||||
$this->assertIsInt($ret);
|
||||
$this->assertEquals(0, $ret);
|
||||
|
||||
/* Get the last 8 approval log entries (actually there are just 6 now) */
|
||||
$approvallog = $content->getApproveLog(8);
|
||||
$this->assertIsArray($approvallog);
|
||||
$this->assertCount(6, $approvallog);
|
||||
$this->assertEquals('Approver removed', $approvallog[0]['comment']);
|
||||
$this->assertEquals(-2, $approvallog[0]['status']);
|
||||
|
||||
/* Now the document will be released again */
|
||||
$newstatus = $content->verifyStatus(false, $user);
|
||||
$this->assertIsInt($newstatus);
|
||||
$this->assertEquals(S_RELEASED, $newstatus);
|
||||
}
|
||||
}
|
365
SeedDMS_Core/tests/SeedDmsBase.php
Normal file
365
SeedDMS_Core/tests/SeedDmsBase.php
Normal file
|
@ -0,0 +1,365 @@
|
|||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Implementation of the database tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
namespace PHPUnit\Framework;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Database test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class SeedDmsTest extends TestCase
|
||||
{
|
||||
|
||||
public static $dbh;
|
||||
|
||||
public static $dms;
|
||||
|
||||
public static $contentdir;
|
||||
|
||||
public static $dbversion;
|
||||
|
||||
/**
|
||||
* Create a sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function createInMemoryDatabase(): object
|
||||
{
|
||||
$dbh = new \SeedDMS_Core_DatabaseAccess('sqlite', '', '', '', ':memory:');
|
||||
$dbh->connect();
|
||||
$queries = file_get_contents(getenv("SEEDDMS_CORE_SQL"));
|
||||
// generate SQL query
|
||||
$queries = explode(";", $queries);
|
||||
|
||||
// execute queries
|
||||
$errorMsg = '';
|
||||
foreach ($queries as $query) {
|
||||
//echo $query;
|
||||
$query = trim($query);
|
||||
if (!empty($query)) {
|
||||
$dbh->getResult($query);
|
||||
|
||||
if ($dbh->getErrorNo() != 0) {
|
||||
//echo $dbh->getErrorMsg()."\n";
|
||||
$errorMsg .= $dbh->getErrorMsg()."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dbh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mocked root folder object
|
||||
*
|
||||
* @return \SeedDMS_Core_Folder
|
||||
*/
|
||||
protected function getMockedRootFolder($id=1, $name='DMS')
|
||||
{
|
||||
$folder = new \SeedDMS_Core_Folder($id, $name, 0, 'DMS root', time(), 1, 0, 0, 0.0);
|
||||
return $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mocked document object
|
||||
*
|
||||
* @return \SeedDMS_Core_Document
|
||||
*/
|
||||
protected function getMockedDocument($id=1, $name='Document')
|
||||
{
|
||||
$document = new \SeedDMS_Core_Document($id, $name, '', time(), null, 1, 1, 1, M_READ, 0, '', 1.0);
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mocked user object
|
||||
*
|
||||
* @return \SeedDMS_Core_User
|
||||
*/
|
||||
protected function getMockedUser()
|
||||
{
|
||||
$user = new \SeedDMS_Core_User(1, 'login', '', 'New User', 'email@seeddms.org', 'de_DE', 'bootstrap', '', null);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporary file with random content and the given length.
|
||||
*
|
||||
* @param integer $length length of file
|
||||
*
|
||||
* @return string name of temporary file
|
||||
*/
|
||||
protected static function createTempFile($length=200, $dir='')
|
||||
{
|
||||
if($tmpfname = @tempnam($dir ? $dir : sys_get_temp_dir(), 'foo')) {
|
||||
file_put_contents($tmpfname, substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', (int) ceil($length/strlen($x)) )),1,$length));
|
||||
return $tmpfname;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporary directory with random name in systems temp dir.
|
||||
*
|
||||
* @param integer $mode access mode of new directory
|
||||
*
|
||||
* @return string name of temporary directory
|
||||
*/
|
||||
protected static function createTempDir(string $dir = null, int $mode = 0700): string {
|
||||
/* Use the system temp dir by default. */
|
||||
if (is_null($dir)) {
|
||||
$dir = sys_get_temp_dir();
|
||||
}
|
||||
|
||||
do { $tmp = $dir . '/' . mt_rand(); }
|
||||
while (!@mkdir($tmp, $mode));
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple document.
|
||||
*
|
||||
* @param \SeedDMS_Core_Folder $parent parent folder
|
||||
* @param \SeedDMS_Core_User $owner owner of document
|
||||
* @param string $name name of document
|
||||
* @param integer $length length of file
|
||||
*
|
||||
* @return string name of temporary file
|
||||
*/
|
||||
protected static function createDocument($parent, $owner, $name, $length=200)
|
||||
{
|
||||
$filename = self::createTempFile($length);
|
||||
list($document, $res) = $parent->addDocument(
|
||||
$name, // name
|
||||
'', // comment
|
||||
null, // no expiration
|
||||
$owner, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file1.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0 // sequence
|
||||
);
|
||||
unlink($filename);
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple folder structure without documents
|
||||
*
|
||||
* DMS root -+- Subfolder 1 -+- Subsubfolder 1 -+- Subsubsubfolder 1
|
||||
* |
|
||||
* +- Subfolder 2
|
||||
* |
|
||||
* +- Subfolder 3
|
||||
*
|
||||
* The sequence field of Subfolder x is:
|
||||
* Subfolder 1: 2.0
|
||||
* Subfolder 2: 1.0
|
||||
* Subfolder 1: 0.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function createSimpleFolderStructure()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
/* Set up a folder structure */
|
||||
$subfolder = $rootfolder->addSubFolder('Subfolder 1', '', $user, 2.0);
|
||||
$subsubfolder = $subfolder->addSubFolder('Subsubfolder 1', '', $user, 1.0);
|
||||
$subsubsubfolder = $subsubfolder->addSubFolder('Subsubsubfolder 1', '', $user, 1.0);
|
||||
$rootfolder->addSubFolder('Subfolder 2', '', $user, 1.0);
|
||||
$rootfolder->addSubFolder('Subfolder 3', '', $user, 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple folder structure with documents
|
||||
*
|
||||
* Creates the same folder structure like createSimpleFolderStructure()
|
||||
* but adds 30 documents to 'Subfolder 1'. They are named 'Document 1'
|
||||
* to 'Document 30'.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function createSimpleFolderStructureWithDocuments()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
self::createSimpleFolderStructure();
|
||||
/* Add documents to 'Subfolder 1' */
|
||||
$subfolder = self::$dms->getFolderByName('Subfolder 1');
|
||||
for ($i=1; $i<=15; $i++) {
|
||||
$filename = self::createTempFile(200);
|
||||
list($document, $res) = $subfolder->addDocument(
|
||||
'Document 1-'.$i, // name
|
||||
'', // comment
|
||||
null,
|
||||
$user, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file-1-'.$i.'.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0+$i // sequence
|
||||
);
|
||||
unlink($filename);
|
||||
}
|
||||
/* Add documents to 'Subfolder 2' */
|
||||
$subfolder = self::$dms->getFolderByName('Subfolder 2');
|
||||
for ($i=1; $i<=15; $i++) {
|
||||
$filename = self::createTempFile(200);
|
||||
list($document, $res) = $subfolder->addDocument(
|
||||
'Document 2-'.$i, // name
|
||||
'', // comment
|
||||
null,
|
||||
$user, // owner
|
||||
'', // keywords
|
||||
[], // categories
|
||||
$filename, // name of file
|
||||
'file-2-'.$i.'.txt', // original file name
|
||||
'.txt', // file type
|
||||
'text/plain', // mime type
|
||||
1.0+$i // sequence
|
||||
);
|
||||
unlink($filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create two groups with 3 users each
|
||||
* The groups are named 'Group 1' and 'Group 2'. The users in Group 1
|
||||
* are named 'User-1-1', 'User-1-2', 'User-1-3'. The users in Group 2
|
||||
* are named 'User-2-1', 'User-2-2', 'User-2-3'.
|
||||
* The login name is the lower case of the name.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function createGroupsAndUsers()
|
||||
{
|
||||
for($i=1; $i<=2; $i++) {
|
||||
$group = self::$dms->addGroup('Group '.$i, '');
|
||||
for($j=1; $j<=3; $j++) {
|
||||
$user = self::$dms->addUser('user-'.$i.'-'.$j, '', 'User '.$j.' in group '.$i, 'user@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$user->joinGroup($group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a workflow with two transitions identical to the traditional
|
||||
* workflow
|
||||
*
|
||||
* NR --- review --> NA -+- approve --> RL
|
||||
* +- reject --> RJ |
|
||||
* +- reject ---> RJ
|
||||
*
|
||||
* States:
|
||||
* NR = needs review
|
||||
* NA = needs approval
|
||||
* RL = released
|
||||
* RJ = rejected
|
||||
*
|
||||
* Actions:
|
||||
* review
|
||||
* approve
|
||||
* reject
|
||||
*
|
||||
* Transitions:
|
||||
* NR -- review -> NA maybe done by reviewer
|
||||
* NR -- reject -> RJ maybe done by reviewer
|
||||
* NA -- approve -> RL maybe done by approver
|
||||
* NA -- reject -> RJ maybe done by approver
|
||||
*/
|
||||
protected function createWorkflow(\SeedDMS_Core_User $reviewer, \SeedDMS_Core_User $approver): \SeedDMS_Core_Workflow
|
||||
{
|
||||
/* Create workflow states */
|
||||
$ws_nr = self::$dms->addWorkflowState('needs review', S_IN_WORKFLOW);
|
||||
$ws_na = self::$dms->addWorkflowState('needs approval', S_IN_WORKFLOW);
|
||||
$ws_rl = self::$dms->addWorkflowState('released', S_RELEASED);
|
||||
$ws_rj = self::$dms->addWorkflowState('rejected', S_REJECTED);
|
||||
|
||||
/* Create workflow actions */
|
||||
$wa_rv = self::$dms->addWorkflowAction('review', S_IN_WORKFLOW);
|
||||
$wa_rj = self::$dms->addWorkflowAction('reject', S_REJECTED);
|
||||
$wa_ap = self::$dms->addWorkflowAction('approve', S_RELEASED);
|
||||
|
||||
/* Create a workflow which starts in state 'needs review' */
|
||||
$workflow = self::$dms->addWorkflow('traditional workflow', $ws_nr);
|
||||
/* Add transition NR -- review -> NA */
|
||||
$wt_nr_na = $workflow->addTransition($ws_nr, $wa_rv, $ws_na, [$reviewer], []);
|
||||
/* Add transition NR -- review -> RJ */
|
||||
$wt_nr_rj = $workflow->addTransition($ws_nr, $wa_rj, $ws_rj, [$reviewer], []);
|
||||
/* Add transition NA -- approve -> RL */
|
||||
$wt_na_rl = $workflow->addTransition($ws_na, $wa_ap, $ws_rl, [$approver], []);
|
||||
/* Add transition NA -- reject -> RJ */
|
||||
$wt_na_rj = $workflow->addTransition($ws_na, $wa_rj, $ws_rj, [$approver], []);
|
||||
|
||||
return $workflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a workflow with one transitions for approving a document
|
||||
*
|
||||
* NA -+- approve --> RL
|
||||
* |
|
||||
* +- reject ---> RJ
|
||||
*
|
||||
* States:
|
||||
* NA = needs approval
|
||||
* RL = released
|
||||
* RJ = rejected
|
||||
*
|
||||
* Actions:
|
||||
* approve
|
||||
* reject
|
||||
*
|
||||
* Transitions:
|
||||
* NA -- approve -> RL maybe done by approver
|
||||
* NA -- reject -> RJ maybe done by approver
|
||||
*/
|
||||
protected function createSimpleWorkflow(\SeedDMS_Core_User $approver): \SeedDMS_Core_Workflow
|
||||
{
|
||||
/* Create workflow states */
|
||||
$ws_na = self::$dms->addWorkflowState('simple needs approval', S_IN_WORKFLOW);
|
||||
$ws_rl = self::$dms->addWorkflowState('simple released', S_RELEASED);
|
||||
$ws_rj = self::$dms->addWorkflowState('simple rejected', S_REJECTED);
|
||||
|
||||
/* Create workflow actions */
|
||||
$wa_rj = self::$dms->addWorkflowAction('simple reject', S_REJECTED);
|
||||
$wa_ap = self::$dms->addWorkflowAction('simple approve', S_RELEASED);
|
||||
|
||||
/* Create a workflow which starts in state 'needs approval' */
|
||||
$workflow = self::$dms->addWorkflow('simple workflow', $ws_na);
|
||||
/* Add transition NA -- approve -> RL */
|
||||
$wt_na_rl = $workflow->addTransition($ws_na, $wa_ap, $ws_rl, [$approver], []);
|
||||
/* Add transition NA -- reject -> RJ */
|
||||
$wt_na_rj = $workflow->addTransition($ws_na, $wa_rj, $ws_rj, [$approver], []);
|
||||
|
||||
return $workflow;
|
||||
}
|
||||
|
||||
}
|
||||
|
1679
SeedDMS_Core/tests/UserTest.php
Normal file
1679
SeedDMS_Core/tests/UserTest.php
Normal file
File diff suppressed because it is too large
Load Diff
638
SeedDMS_Core/tests/WorkflowTest.php
Normal file
638
SeedDMS_Core/tests/WorkflowTest.php
Normal file
|
@ -0,0 +1,638 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of the workflow tests
|
||||
*
|
||||
* PHP version 7
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\SeedDmsTest;
|
||||
|
||||
/**
|
||||
* Group test class
|
||||
*
|
||||
* @category SeedDMS
|
||||
* @package Tests
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2021 Uwe Steinmann
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
|
||||
* @version Release: @package_version@
|
||||
* @link https://www.seeddms.org
|
||||
*/
|
||||
class WorkflowTest extends SeedDmsTest
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a real sqlite database in memory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::$dbh = self::createInMemoryDatabase();
|
||||
self::$contentdir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'phpunit-'.time();
|
||||
mkdir(self::$contentdir);
|
||||
// echo "Creating temp content dir: ".self::$contentdir."\n";
|
||||
self::$dms = new \SeedDMS_Core_DMS(self::$dbh, self::$contentdir);
|
||||
self::$dbversion = self::$dms->getDBVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up at tear down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
self::$dbh = null;
|
||||
// echo "\nRemoving temp. content dir: ".self::$contentdir."\n";
|
||||
exec('rm -rf '.self::$contentdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getInitState() and setInitState()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetInitState()
|
||||
{
|
||||
$ws_nr = self::$dms->addWorkflowState('needs review', S_IN_WORKFLOW);
|
||||
$ws_na = self::$dms->addWorkflowState('needs approval', S_IN_WORKFLOW);
|
||||
$workflow = self::$dms->addWorkflow('traditional workflow', $ws_nr);
|
||||
$initstate = $workflow->getInitState();
|
||||
$this->assertEquals($ws_nr->getName(), $initstate->getName());
|
||||
$ret = $workflow->setInitState($ws_na);
|
||||
$this->assertTrue($ret);
|
||||
$initstate = $workflow->getInitState();
|
||||
$this->assertEquals($ws_na->getName(), $initstate->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getName() and setName()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetStateName()
|
||||
{
|
||||
$state = self::$dms->addWorkflowState('needs review', S_IN_WORKFLOW);
|
||||
$name = $state->getName();
|
||||
$this->assertEquals('needs review', $name);
|
||||
$ret = $state->setName('foobar');
|
||||
$this->assertTrue($ret);
|
||||
$name = $state->getName();
|
||||
$this->assertEquals('foobar', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getName() and setName()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetActionName()
|
||||
{
|
||||
$action = self::$dms->addWorkflowAction('action');
|
||||
$name = $action->getName();
|
||||
$this->assertEquals('action', $name);
|
||||
$ret = $action->setName('foobar');
|
||||
$this->assertTrue($ret);
|
||||
$name = $action->getName();
|
||||
$this->assertEquals('foobar', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getName() and setName()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetWorkflowName()
|
||||
{
|
||||
$ws_nr = self::$dms->addWorkflowState('needs review', S_IN_WORKFLOW);
|
||||
$workflow = self::$dms->addWorkflow('traditional workflow', $ws_nr);
|
||||
$name = $workflow->getName();
|
||||
$this->assertEquals('traditional workflow', $name);
|
||||
$ret = $workflow->setName('foo');
|
||||
$this->assertTrue($ret);
|
||||
$name = $workflow->getName();
|
||||
$this->assertEquals('foo', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getDocumentStatus() and setDocumentStatus()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetAndSetDocumentStatus()
|
||||
{
|
||||
$state = self::$dms->addWorkflowState('some name', S_RELEASED);
|
||||
$docstatus = $state->getDocumentStatus();
|
||||
$this->assertEquals(S_RELEASED, $docstatus);
|
||||
$ret = $state->setDocumentStatus(S_REJECTED);
|
||||
$this->assertTrue($ret);
|
||||
$docstatus = $state->getDocumentStatus();
|
||||
$this->assertEquals(S_REJECTED, $docstatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method workflow->remove()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateAndRemoveWorkflow()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertIsObject($user);
|
||||
|
||||
/* Add a new user who will be the reviewer */
|
||||
$reviewer = self::$dms->addUser('reviewer', 'reviewer', 'Reviewer One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($reviewer);
|
||||
|
||||
/* Add a new user who will be the approver */
|
||||
$approver = self::$dms->addUser('approver', 'approver', 'Approver One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($approver);
|
||||
|
||||
$workflow = self::createWorkflow($reviewer, $approver);
|
||||
$this->assertIsObject($workflow);
|
||||
|
||||
$ret = $workflow->remove();
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$states = self::$dms->getAllWorkflowStates();
|
||||
$this->assertIsArray($states);
|
||||
$this->assertCount(4, $states);
|
||||
foreach($states as $state)
|
||||
$this->assertFalse($state->isUsed());
|
||||
|
||||
$actions = self::$dms->getAllWorkflowActions();
|
||||
$this->assertIsArray($actions);
|
||||
$this->assertCount(3, $actions);
|
||||
foreach($actions as $action)
|
||||
$this->assertFalse($action->isUsed());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method remove()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateAndRemoveAction()
|
||||
{
|
||||
$action = self::$dms->addWorkflowAction('action');
|
||||
$this->assertIsObject($action);
|
||||
$actions = self::$dms->getAllWorkflowActions();
|
||||
$this->assertIsArray($actions);
|
||||
$this->assertCount(1, $actions);
|
||||
$ret = $action->remove();
|
||||
$this->assertTrue($ret);
|
||||
$actions = self::$dms->getAllWorkflowActions();
|
||||
$this->assertIsArray($actions);
|
||||
$this->assertCount(0, $actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method remove()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateAndRemoveState()
|
||||
{
|
||||
$state = self::$dms->addWorkflowState('needs review', S_IN_WORKFLOW);
|
||||
$this->assertIsObject($state);
|
||||
$states = self::$dms->getAllWorkflowStates();
|
||||
$this->assertIsArray($states);
|
||||
$this->assertCount(1, $states);
|
||||
$ret = $state->remove();
|
||||
$this->assertTrue($ret);
|
||||
$states = self::$dms->getAllWorkflowStates();
|
||||
$this->assertIsArray($states);
|
||||
$this->assertCount(0, $states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setWorkflow(), getWorkflow(), getWorkflowState()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAssignWorkflow()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertIsObject($user);
|
||||
|
||||
/* Add a new user who will be the reviewer */
|
||||
$reviewer = self::$dms->addUser('reviewer', 'reviewer', 'Reviewer One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($reviewer);
|
||||
|
||||
/* Add a new user who will be the approver */
|
||||
$approver = self::$dms->addUser('approver', 'approver', 'Approver One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($approver);
|
||||
|
||||
$workflow = self::createWorkflow($reviewer, $approver);
|
||||
$this->assertIsObject($workflow);
|
||||
|
||||
/* Check for cycles */
|
||||
$cycles = $workflow->checkForCycles();
|
||||
$this->assertFalse($cycles);
|
||||
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$content = $document->getLatestContent();
|
||||
$this->assertIsObject($content);
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
/* Assign the workflow */
|
||||
$ret = $content->setWorkflow($workflow, $user);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Assign a workflow again causes an error */
|
||||
$ret = $content->setWorkflow($workflow, $user);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* Get a fresh copy of the content from the database and get the workflow */
|
||||
$again = self::$dms->getDocumentContent($content->getId());
|
||||
$this->assertIsObject($again);
|
||||
$w = $again->getWorkflow();
|
||||
$this->assertEquals($workflow->getId(), $w->getId());
|
||||
|
||||
/* Status of content should be S_IN_WORKFLOW now */
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_IN_WORKFLOW, $status['status']);
|
||||
|
||||
/* Get current workflow state */
|
||||
$state = $content->getWorkflowState();
|
||||
$this->assertEquals('needs review', $state->getName());
|
||||
|
||||
$workflowlog = $content->getWorkflowLog();
|
||||
$this->assertIsArray($workflowlog);
|
||||
$this->assertCount(0, $workflowlog);
|
||||
|
||||
/* The workflow has altogether 4 states */
|
||||
$states = $workflow->getStates();
|
||||
$this->assertIsArray($states);
|
||||
$this->assertCount(4, $states);
|
||||
|
||||
/* Check the initial state */
|
||||
$initstate = $workflow->getInitState();
|
||||
$this->assertEquals('needs review', $initstate->getName());
|
||||
|
||||
/* init state is definitely used */
|
||||
$ret = $initstate->isUsed();
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* init state has two transistions linked to it */
|
||||
$transitions = $initstate->getTransitions();
|
||||
$this->assertIsArray($transitions);
|
||||
$this->assertCount(2, $transitions);
|
||||
|
||||
/* Check if workflow is used by any document */
|
||||
$isused = $workflow->isUsed();
|
||||
$this->assertTrue($isused);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method setWorkflow(), getWorkflow(), getWorkflowState()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testStepThroughWorkflow()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertIsObject($user);
|
||||
|
||||
/* Add a new user who will be the reviewer */
|
||||
$reviewer = self::$dms->addUser('reviewer', 'reviewer', 'Reviewer One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($reviewer);
|
||||
|
||||
/* Add a new user who will be the approver */
|
||||
$approver = self::$dms->addUser('approver', 'approver', 'Approver One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($approver);
|
||||
|
||||
$workflow = self::createWorkflow($reviewer, $approver);
|
||||
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$content = $document->getLatestContent();
|
||||
$this->assertIsObject($content);
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
/* Assign the workflow */
|
||||
$ret = $content->setWorkflow($workflow, $user);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_IN_WORKFLOW, $status['status']);
|
||||
|
||||
/* Remove the workflow */
|
||||
$ret = $content->removeWorkflow($user);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
/* Remove the workflow again is just fine */
|
||||
$ret = $content->removeWorkflow($user);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Assign the workflow again */
|
||||
$ret = $content->setWorkflow($workflow, $user);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_IN_WORKFLOW, $status['status']);
|
||||
|
||||
|
||||
/* Check if workflow needs action by the reviewer/approver */
|
||||
$ret = $content->needsWorkflowAction($reviewer);
|
||||
$this->assertTrue($ret);
|
||||
$ret = $content->needsWorkflowAction($approver);
|
||||
$this->assertFalse($ret);
|
||||
|
||||
/* Get current workflow state*/
|
||||
$state = $content->getWorkflowState();
|
||||
$this->assertEquals('needs review', $state->getName());
|
||||
|
||||
/* There should be two possible transitions now
|
||||
* NR -- review -> NA
|
||||
* NR -- reject -> RJ
|
||||
*/
|
||||
$nexttransitions = $workflow->getNextTransitions($state);
|
||||
$this->assertIsArray($nexttransitions);
|
||||
$this->assertCount(2, $nexttransitions);
|
||||
|
||||
/* But of course, there were no previous transitions */
|
||||
$prevtransitions = $workflow->getPreviousTransitions($state);
|
||||
$this->assertIsArray($prevtransitions);
|
||||
$this->assertCount(0, $prevtransitions);
|
||||
|
||||
/* Check if reviewer is allowed to trigger the transition.
|
||||
* As we are still in the intitial state, the possible transitions
|
||||
* may both be triggered by the reviewer but not by the approver.
|
||||
*/
|
||||
foreach($nexttransitions as $nexttransition) {
|
||||
if($nexttransition->getNextState()->getDocumentStatus() == S_REJECTED)
|
||||
$rejecttransition = $nexttransition;
|
||||
elseif($nexttransition->getNextState()->getDocumentStatus() == S_IN_WORKFLOW)
|
||||
$reviewtransition = $nexttransition;
|
||||
$ret = $content->triggerWorkflowTransitionIsAllowed($reviewer, $nexttransition);
|
||||
$this->assertTrue($ret);
|
||||
$ret = $content->triggerWorkflowTransitionIsAllowed($approver, $nexttransition);
|
||||
$this->assertFalse($ret);
|
||||
}
|
||||
|
||||
/* Trigger the successful review transition.
|
||||
* As there is only one reviewer the transition will fire and the workflow
|
||||
* moves forward into the next state. triggerWorkflowTransition() returns the
|
||||
* next state.
|
||||
*/
|
||||
$nextstate = $content->triggerWorkflowTransition($reviewer, $reviewtransition, 'Review succeeded');
|
||||
$this->assertIsObject($nextstate);
|
||||
$this->assertEquals('needs approval', $nextstate->getName());
|
||||
|
||||
$state = $content->getWorkflowState();
|
||||
$this->assertEquals($nextstate->getId(), $state->getId());
|
||||
$this->assertEquals('needs approval', $state->getName());
|
||||
|
||||
/* The workflow log has one entry now */
|
||||
$workflowlog = $content->getLastWorkflowLog();
|
||||
$this->assertIsObject($workflowlog);
|
||||
$this->assertEquals('Review succeeded', $workflowlog->getComment());
|
||||
|
||||
/* There should be two possible transitions now
|
||||
* NA -- approve -> RL
|
||||
* NA -- reject -> RJ
|
||||
*/
|
||||
$nexttransitions = $workflow->getNextTransitions($state);
|
||||
$this->assertIsArray($nexttransitions);
|
||||
$this->assertCount(2, $nexttransitions);
|
||||
|
||||
/* But of course, there is one previous transitions, the one that led to
|
||||
* the current state of the workflow.
|
||||
*/
|
||||
$prevtransitions = $workflow->getPreviousTransitions($state);
|
||||
$this->assertIsArray($prevtransitions);
|
||||
$this->assertCount(1, $prevtransitions);
|
||||
$this->assertEquals($reviewtransition->getId(), $prevtransitions[0]->getId());
|
||||
|
||||
/* Check if approver is allowed to trigger the transition.
|
||||
* As we are now in 'needs approval' state, the possible transitions
|
||||
* may both be triggered by the approver but not by the reviewer.
|
||||
*/
|
||||
foreach($nexttransitions as $nexttransition) {
|
||||
if($nexttransition->getNextState()->getDocumentStatus() == S_REJECTED)
|
||||
$rejecttransition = $nexttransition;
|
||||
elseif($nexttransition->getNextState()->getDocumentStatus() == S_RELEASED)
|
||||
$releasetransition = $nexttransition;
|
||||
$ret = $content->triggerWorkflowTransitionIsAllowed($approver, $nexttransition);
|
||||
$this->assertTrue($ret);
|
||||
$ret = $content->triggerWorkflowTransitionIsAllowed($reviewer, $nexttransition);
|
||||
$this->assertFalse($ret);
|
||||
}
|
||||
|
||||
/* Trigger the successful approve transition.
|
||||
* As there is only one approver the transition will fire and the workflow
|
||||
* moves forward into the next state. triggerWorkflowTransition() returns the
|
||||
* next state.
|
||||
*/
|
||||
$nextstate = $content->triggerWorkflowTransition($approver, $releasetransition, 'Approval succeeded');
|
||||
$this->assertIsObject($nextstate);
|
||||
$this->assertEquals('released', $nextstate->getName());
|
||||
|
||||
/* The workflow log has two entries now */
|
||||
$workflowlog = $content->getLastWorkflowLog();
|
||||
$this->assertIsObject($workflowlog);
|
||||
$this->assertEquals('Approval succeeded', $workflowlog->getComment());
|
||||
|
||||
/* Because the workflow has reached a final state, the workflow will no
|
||||
* longer be attached to the document.
|
||||
*/
|
||||
$workflow = $content->getWorkflow();
|
||||
$this->assertFalse($workflow);
|
||||
|
||||
/* There is also no way to get the state anymore */
|
||||
$state = $content->getWorkflowState();
|
||||
$this->assertFalse($state);
|
||||
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
/* Even after the workflow has been finished the log can still be retrieved */
|
||||
$workflowlog = $content->getLastWorkflowLog();
|
||||
$this->assertIsObject($workflowlog);
|
||||
$this->assertEquals('Approval succeeded', $workflowlog->getComment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method rewindWorkflow()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRewindWorkflow()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertIsObject($user);
|
||||
|
||||
/* Add a new user who will be the reviewer */
|
||||
$reviewer = self::$dms->addUser('reviewer', 'reviewer', 'Reviewer One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($reviewer);
|
||||
|
||||
/* Add a new user who will be the approver */
|
||||
$approver = self::$dms->addUser('approver', 'approver', 'Approver One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($approver);
|
||||
|
||||
$workflow = self::createWorkflow($reviewer, $approver);
|
||||
|
||||
/* Add a new document */
|
||||
$document = self::createDocument($rootfolder, $user, 'Document 1');
|
||||
$content = $document->getLatestContent();
|
||||
$this->assertIsObject($content);
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_RELEASED, $status['status']);
|
||||
|
||||
/* Assign the workflow */
|
||||
$ret = $content->setWorkflow($workflow, $user);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
$status = $content->getStatus();
|
||||
$this->assertIsArray($status);
|
||||
$this->assertEquals(S_IN_WORKFLOW, $status['status']);
|
||||
|
||||
/* Check if workflow needs action by the reviewer */
|
||||
$ret = $content->needsWorkflowAction($reviewer);
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* Get current workflow state*/
|
||||
$state = $content->getWorkflowState();
|
||||
$this->assertEquals('needs review', $state->getName());
|
||||
|
||||
/* There should be two possible transitions now
|
||||
* NR -- review -> NA
|
||||
* NR -- reject -> RJ
|
||||
*/
|
||||
$nexttransitions = $workflow->getNextTransitions($state);
|
||||
$this->assertIsArray($nexttransitions);
|
||||
$this->assertCount(2, $nexttransitions);
|
||||
|
||||
/* Check if reviewer is allowed to trigger the transition.
|
||||
* As we are still in the intitial state, the possible transitions
|
||||
* may both be triggered by the reviewer but not by the approver.
|
||||
*/
|
||||
foreach($nexttransitions as $nexttransition) {
|
||||
if($nexttransition->getNextState()->getDocumentStatus() == S_IN_WORKFLOW)
|
||||
$reviewtransition = $nexttransition;
|
||||
}
|
||||
|
||||
/* Trigger the successful review transition.
|
||||
* As there is only one reviewer the transition will fire and the workflow
|
||||
* moves forward into the next state. triggerWorkflowTransition() returns the
|
||||
* next state.
|
||||
*/
|
||||
$nextstate = $content->triggerWorkflowTransition($reviewer, $reviewtransition, 'Review succeeded');
|
||||
$this->assertIsObject($nextstate);
|
||||
$this->assertEquals('needs approval', $nextstate->getName());
|
||||
|
||||
/* Get current workflow state*/
|
||||
$state = $content->getWorkflowState();
|
||||
$this->assertEquals('needs approval', $state->getName());
|
||||
|
||||
/* The workflow log has one entry now */
|
||||
$workflowlogs = $content->getWorkflowLog();
|
||||
$this->assertIsArray($workflowlogs);
|
||||
$this->assertCount(1, $workflowlogs);
|
||||
if(self::$dbversion['major'] > 5)
|
||||
$this->assertEquals('Review succeeded', $workflowlogs[1][0]->getComment());
|
||||
else
|
||||
$this->assertEquals('Review succeeded', $workflowlogs[0]->getComment());
|
||||
|
||||
$ret = $content->rewindWorkflow();
|
||||
$this->assertTrue($ret);
|
||||
|
||||
/* After rewinding the workflow the initial state is set ... */
|
||||
$state = $content->getWorkflowState();
|
||||
$this->assertEquals('needs review', $state->getName());
|
||||
|
||||
/* and the workflow log has been cleared */
|
||||
$workflowlogs = $content->getWorkflowLog();
|
||||
$this->assertIsArray($workflowlogs);
|
||||
$this->assertCount(0, $workflowlogs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method getTransitionsByStates()
|
||||
*
|
||||
* This method uses a real in memory sqlite3 database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTransitionsByStateWorkflow()
|
||||
{
|
||||
$rootfolder = self::$dms->getRootFolder();
|
||||
$user = self::$dms->getUser(1);
|
||||
$this->assertIsObject($user);
|
||||
|
||||
/* Add a new user who will be the reviewer */
|
||||
$reviewer = self::$dms->addUser('reviewer', 'reviewer', 'Reviewer One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($reviewer);
|
||||
|
||||
/* Add a new user who will be the approver */
|
||||
$approver = self::$dms->addUser('approver', 'approver', 'Approver One', 'user1@seeddms.org', 'en_GB', 'bootstrap', '');
|
||||
$this->assertIsObject($approver);
|
||||
|
||||
$workflow = self::createWorkflow($reviewer, $approver);
|
||||
|
||||
/* Check the initial state */
|
||||
$initstate = $workflow->getInitState();
|
||||
$this->assertEquals('needs review', $initstate->getName());
|
||||
|
||||
/* init state has two transistions linked to it */
|
||||
$transitions = $initstate->getTransitions();
|
||||
$this->assertIsArray($transitions);
|
||||
$this->assertCount(2, $transitions);
|
||||
|
||||
$t = $workflow->getTransitionsByStates($initstate, $transitions[1]->getNextState());
|
||||
$this->assertEquals($transitions[1]->getId(), $t[0]->getId());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user