Skip to content

Test results

open-pryv.io 2.0.0-pre.2

Summary

1275tests total
1259✅ passing
16❓ pending
0❌ failing

Date: 2026-04-11T07:56:06.000Z

api-server component

Summary

906tests total
891✅ passing
15❓ pending
0❌ failing

Tests

IdStatusTest
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD07] to create an access for visible account streams [AD08] with a read-level permission
idUE9G✅should return 201
idBUYP✅should create access in the database
idS3IQ✅should enable user to read visible stream event with this access
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD07] to create an access for visible account streams [AD08] with a read-level permission [AD09] for the "account" stream
idXEAK✅should return 201
id65I4✅should create access in the database
idL99L✅should allow to access visible events in storageUsed
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD07] to create an access for visible account streams [AD08] with a read-level permission [AD10] for the "storageUsed" stream
idEPEP✅should return 201
idU3UM✅should create access in the database
idA4UP✅should allow to access visible events in storageUsed
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD07] to create an access for visible account streams [AD11] with a create-only-level permission
idIWMQ✅should return 201
idAPYN✅should create access in the database
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD07] to create an access for visible account streams [AD12] with a contribute-level permission
idR0M1✅should return 201
idQ8R8✅should create access in the database
idTI1X✅should allow to create visible stream events
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD07] to create an access for visible account streams [AD13] with a manage-level permission
id93HO✅should return 400
idYPHX✅should return the correct error
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD14] to create an access for not visible account streams
idATGU✅should return 400
idQ2KZ✅should return the correct error
[AD01] Accesses with account streams [AD02] POST /accesses [AD03] When using a personal access [AD15] to create an access for unexisting system streams
idKKKS✅should return 403 forbidden
[AD01] Accesses with account streams [AD04] DELETE /accesses [AD05] When using a personal access [AD06] to delete an account stream access
idZ40J✅should return 200
idMP9T✅should delete the access in the database
[AC01] accesses [AC02] access deletions [AC03] when given a few existing accesses [AC04] accesses.get
idH7ZS✅access should contain tokens and apiEndpoints
idP12L✅should contain deletions
idBQ7M✅contains active accesses
idNVCQ✅contains deleted accesses as well
id6ZQL✅deleted access are in UTC (seconds) format
[AC01] accesses [AC02] access deletions [AC03] when given a few existing accesses [AC05] accesses.create [AC06] for a valid access
idN3Q1✅should contain an access
id8UOW✅access should contain token and apiEndpoint
idJ77Z✅should contain the set values, but no “deleted” field in the API response
idA4JP✅should contain the field “deleted:null” in the database
[AC01] accesses [AC02] access deletions [AC03] when given a few existing accesses [AC05] accesses.create [AC07] for a deleted access
id1DJ6✅should return an error
id7ZPK✅error should say that the deleted field is forbidden upon creation
[AC01] accesses [AC02] access deletions [AC03] when given a few existing accesses [AC08] accesses.update
idJNJK✅should return an error
idOS36✅error should say that the deleted field is forbidden upon update
[AC01] accesses [AC09] Delete app access [AC10] when deleting an app access that created shared accesses
idWE2O✅should return the accessDeletion and relatedDeletions
idIVWP✅should delete it and the accesses it created, not touching the expired ones
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC13] accesses.get [AC14] vanilla version
id489J✅succeeds
id7NPE✅contains only active accesses
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC13] accesses.get [AC15] when given the includeExpired=true parameter
idPIGE✅succeeds
idDZHL✅includes expired accesses
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC16] accesses.create [AC17] when called with expireAfter>0
id3ONA✅creates an access with set expiry timestamp
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC16] accesses.create [AC18] when called with expireAfter=0
id8B65✅creates an expired access
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC16] accesses.create [AC19] when called with expireAfter<0
idJHWH✅fails
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC16] accesses.create [AC20] Store accesses
idJZWH✅create an access on :dummy: store
idJUWH✅create an access :dummy:marcella on :dummy: store
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC21] accesses.checkApp [AC22] when the matching access is not expired
idB66B✅returns the matching access
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC21] accesses.checkApp [AC23] when the matching access is expired
idDLHJ✅returns no match
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC24] other API accesses [AC25] using an expired access
idAJG5✅fails
idKGT4✅returns a proper error message
[AC01] accesses [AC11] access expiry [AC12] when given a few existing accesses [AC24] other API accesses [AC26] using a valid access
idCBRF✅succeeds
[AC01] accesses [AC27] access client data [AC28] when given a few existing accesses [AC29] accesses.get
idKML2✅succeeds
idNY85✅contains existing accesses with clientData
[AC01] accesses [AC27] access client data [AC28] when given a few existing accesses [AC30] accesses.create [AC31] when called with clientData={}
idOMUO✅creates an access with empty clientData
[AC01] accesses [AC27] access client data [AC28] when given a few existing accesses [AC30] accesses.create [AC32] when called with clientData=null
idE5C1✅throws a schema error
[AC01] accesses [AC27] access client data [AC28] when given a few existing accesses [AC30] accesses.create [AC33] when called with complex clientData
idJYD4✅creates an access with complex clientData
[AC01] accesses [AC27] access client data [AC28] when given a few existing accesses [AC34] accesses.checkApp [AC35] when the provided clientData matches the existing clientData
idU1AM✅returns the matching access
[AC01] accesses [AC27] access client data [AC28] when given a few existing accesses [AC34] accesses.checkApp [AC36] when the provided clientData does not match the existing clientData
id2EER✅returns no match
[AC01] accesses [AC27] access client data [AC28] when given a few existing accesses [AC34] accesses.checkApp [AC37] when no clientData is provided but existing access has one
idDHZQ✅returns no match
[AC01] accesses [AC38] access-info
idPH0K✅should return the username
[ACCO] Account with system streams [DA01] GET /account [DA02] and when user has multiple events per stream and additional streams events
idXRKX✅should return 200
idJUHR✅should return account information in the structure that is defined in system streams and only active values
idR5S0✅should return only visible default stream events
[ACCO] Account with system streams [DA03] POST /change-password [DA04] and when valid data is provided
idX9VQ✅should return 200
idACNE✅should find password in password history
[ACCO] Account with system streams [DA05] PUT /account [DA06] when updating the username
idP69J✅should return 400
idDBM6✅should return the correct error
[ACCO] Account with system streams [DA05] PUT /account [DA07] when updating non editable fields
id90N3✅should return 400
idQHZ4✅should return the correct error
[ACCO] Account with system streams [DA05] PUT /account [DA08] when updating a unique field that is already taken [DA09] and the field is not unique in PlatformDB
idK3X9✅should return a 409 error
id8TRP✅should return the correct error
[ACCO] Account with system streams [DA05] PUT /account [DA10] when updating email and language
idJJ81✅should return 200
idK9IC✅should returned updated account data
idJQHX✅should update the field values in the database
[AUDI] Audit logs events (Pattern C) [AU01] GET /events
id0BK7✅must not return null values or trashed=false
idVBV0✅must not return “auth” in “content:query”
idR8MS✅must escape special characters
[AUDI] Audit logs events (Pattern C) [AU02] GET /audit/logs
idRV4W✅must return a valid id field
[FG5R] Events of system streams [ED01] GET /events [ED02] When using a personal access
idKS6K✅should return visible system events only
[FG5R] Events of system streams [ED01] GET /events [ED03] When using a shared access with a read-level permission on the .account stream
idDRFH✅should return visible system events only
[FG5R] Events of system streams [ED01] GET /events [ED04] When using a shared access with a read-level permission on all streams (star) and a visible system stream
idGF3A✅should return only the account event for which a permission was explicitely provided
[FG5R] Events of system streams [ED01] GET /events [ED05] When using a shared access with a read-level permission on all streams (star)
idRM74✅should not return any system events
[FG5R] Events of system streams [ED06] GET /events/ [ED10] When using a personal access [ED11] to retrieve a visible system event
id9IEX✅should return 200
idIYE6✅should return the event
[FG5R] Events of system streams [ED06] GET /events/ [ED10] When using a personal access [ED12] to retrieve a non visible system event
idY2OA✅should return 403
idDHZE✅should return the right error message
[FG5R] Events of system streams [ED06] GET /events/ [ED13] When using a shared access with a read-level permission on all streams (star) and a visible system stream
idYPZX✅should return 200
id1NRM✅should return the event
[FG5R] Events of system streams [ED07] POST /events [ED14] When using a personal access [ED15] to create an editable system event [ED16] which is non indexed and non unique
idF308✅should return 201
id9C2D✅should return the created event
idA9DC✅should update the field value (single event per field)
[FG5R] Events of system streams [ED07] POST /events [ED14] When using a personal access [ED15] to create an editable system event [ED17] which is indexed [ED18] when the new value is valid
id8C80✅should return 201
id67F7✅should return the created event
id467D✅should update the field value (single event per field)
[FG5R] Events of system streams [ED07] POST /events [ED14] When using a personal access [ED15] to create an editable system event [ED17] which is indexed [ED19] when the new value is invalid
idPQHR✅should return 400
[FG5R] Events of system streams [ED07] POST /events [ED14] When using a personal access [ED15] to create an editable system event [ED20] which is indexed and unique [WCIU] whose content is unique
idSQZ2✅should return 201
idYS79✅should return the created event
idDA23✅should update the field value (single event per field)
[FG5R] Events of system streams [ED07] POST /events [ED14] When using a personal access [ED15] to create an editable system event [ED20] which is indexed and unique [ED21] whose content is already taken by another user
id89BC✅should return 409
id10BC✅should return the correct error
[FG5R] Events of system streams [ED07] POST /events [ED14] When using a personal access [ED15] to create an editable system event [ED20] which is indexed and unique [6B8D] When creating an event with an email already taken by another user
id2021✅should return a 409 error
id121E✅should return the correct error
[FG5R] Events of system streams [ED07] POST /events [ED14] When using a personal access [ED22] to create a non editable system event
id6CE0✅should return a 400 error
id90E6✅should return the correct error
[FG5R] Events of system streams [ED07] POST /events [ED23] when using a shared access with a contribute-level permission on a system stream
idX49R✅should return 201
id764A✅should return the created event
[FG5R] Events of system streams [ED07] POST /events [ED24] when using a shared access with a manage-level permission on all streams (star)
idYX07✅should return 403
idYYU1✅should return correct error id
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED27] which is non indexed and non unique
id2FA2✅should return 200
id763A✅should return the updated event
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED27] which is non indexed and non unique [ED29] by changing its steamIds [ED30] when editing with 2 streamIds at the time
id8BFK✅should return 400
idE3KE✅should return the correct error
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED27] which is non indexed and non unique [ED29] by changing its steamIds [ED31] when substituting a system stream with another one
id9004✅should return 400
idE3AE✅should return the correct error
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED32] which is indexed [ED33] as register is working [ED34] when the new value is valid
id0RUK✅should return 200
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED32] which is indexed [ED33] as register is working [ED36] when the new value is invalid
idRDZF✅should return 400
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED32] which is indexed [ED37] without external register (PlatformDB handles all)
idAA92✅should return 200
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED38] which is unique [ED39] by updating a unique field that is valid
id4BB1✅should return 200
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED38] which is unique [ED41] by updating a unique field that is already taken [ED42] with a field that is already taken by another user
idF8A8✅should return 409
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED26] to update an editable system event [ED38] which is unique [ED41] by updating a unique field that is already taken [ED43] with a field that is not unique in mongodb
id5782✅should return 409
idB285✅should return the correct error
[FG5R] Events of system streams [ED08] PUT /events/ [ED25] when using a personal access [ED44] to update a non editable system event
id034D✅should return 400
idBB5F✅should return the correct error
[FG5R] Events of system streams [ED08] PUT /events/ [ED45] when using a shared access with a contribute-level access on a system stream [ED46] to update an editable system event
idW8PQ✅should return 200
idTFOI✅should return the updated event
[FG5R] Events of system streams [ED08] PUT /events/ [ED47] when using a shared access with a manage-level permission on all streams (star) [ED48] to update an editable system event
idH1XL✅should return 403
id7QA3✅should return the correct error
[FG5R] Events of system streams [ED09] DELETE /events/ [ED49] When using a personal access [ED50] to delete an account event [ED52] which is unique
id43B1✅should return 400
id3E12✅should return the correct error
[FG5R] Events of system streams [ED09] DELETE /events/ [ED49] When using a personal access [ED50] to delete an account event [ED53] which is indexed
id1B70✅should return 400
idCBB9✅should return the correct error
[FG5R] Events of system streams [ED09] DELETE /events/ [ED49] When using a personal access [ED55] to delete a non editable system event
id8EDB✅should return a 400
idA727✅should return the correct error
[FG5R] Events of system streams [ED09] DELETE /events/ [ED56] when using a shared access with a contribute-level access on a system stream
idI1I1✅should return 400
idUFLT✅should return the correct error
[FG5R] Events of system streams [ED09] DELETE /events/ [ED57] when using a shared access with a manage-level permission on all streams (star)
idAT1E✅should return 403
idFV8W✅should return the correct error
[SYSS] System streams [SS01] GET /streams [SS02] When using a personal access
id9CGO✅Should return all streams - including system ones
[SYSS] System streams [SS03] POST /streams [SS04] When using a personal access [SS05] to create a child to a system stream
idGRI4✅should return status 400
idXP07✅should return the correct error
[SYSS] System streams [SS06] PUT /streams/ [SS07] When using a personal access [SS08] to update a system stream
idSLIR✅should return status 400
idV6HC✅should return the correct error
[SYSS] System streams [SS09] DELETE /streams/ [SS10] When using a personal access [SS11] to delete a system stream
id1R35✅should return status 400
id4939✅should return the correct error
[ACCP] accesses (app) [AA01] GET /
idYEHW✅must return shared accesses whose permissions are a subset of the current one’s
idGLHP✅must be forbidden to requests with a shared access token
[ACCP] accesses (app) [AA02] POST /
idQVHS✅must create a new shared access with the sent data and return it
id6GR1✅must forbid trying to create a non-shared access
idA4MC✅must forbid trying to create an access with greater permissions
idQN6D✅must return a correct error if the sent data is badly formatted
id4HAE✅must allow creation of shared accesses with an access that has superior permission on root stream (*)
[ACCP] accesses (app) [AA03] PUT /
id11UZ✅must return a 410 (Gone)
[ACCP] accesses (app) [AA04] DELETE /
id5BOO✅must delete the shared access
idZTSX✅forbid deletion of already deleted for AppTokens
idVGQS✅must forbid trying to delete a non-shared access
idZTSY✅must forbid trying to delete an access that was not created by itself
idJ32P✅must return a correct error if the access does not exist
[ACSF] accesses (personal) [AS01] GET /
idK5BF✅must return all accesses (including personal ones)
[ACSF] accesses (personal) [AS02] POST /
idBU9U✅must create a new shared access with the sent data, returning it
idFPUE✅must create a new app access with the sent data, creating/restoring requested streams
id865I✅must accept two app accesses with the same name (app ids) but different device names
id4Y3Y✅must ignore erroneous requests to create new streams
idWSG8✅must fail if a stream similar to that requested for creation already exists
idGVC7✅must refuse to create new personal accesses (obtained via login only)
idYRNE✅must slugify the new access’ predefined token
id00Y3✅must return an error if a permission’s streamId has an invalid format
idV3AV✅must return an error if the sent data is badly formatted
idHETK✅must refuse empty defaultName values for streams
idYG81✅must return an error if an access with the same token already exists
idGZTH✅must return an error if an shared access with the same name already exists
id4HO6✅must return an error if an “app” access with the same name (app id) and device name already exists
idPO0R✅must return an error if the device name is set for a non-app access
idRWGG✅must return an error if the given predefined access’s token is a reserved word
id08SK✅must return an error if the permission streamId has invalid characters
[ACSF] accesses (personal) [AS03] PUT /
idU04A✅must return a 410 (Gone)
[ACSF] accesses (personal) [AS04] DELETE /
idS8EK✅must delete the shared access
id5GBI✅must delete the personal access
idNN11✅must return an error if the access does not exist
[ACSF] accesses (personal) [AS05] POST /check-app
idVCH9✅must return the adjusted permissions structure if no access exists
idR8H5✅must accept requested permissions with store “:dummy:” and adapt to correct name
idR8H4✅must accept requested permissions with “*” for “all streams”
id9QNK✅must return the existing app access if matching
idIF33✅must also return the token of the existing mismatching access if any
idG5T2✅must propose fixes to duplicate ids of streams and signal an error when appropriate
idMTY1✅must return an error if the sent data is badly formatted
idU5KD✅must be forbidden to non-personal accesses
[ACCO] account [AC02] PUT /
id0PPV✅must modify account details with the sent data
[ACCO] account [AC03] storage space monitoring
idNFJQ✅must properly compute used storage size for a given user when called
idY445✅must properly compute storage size for all users in nightly script
id0QVH✅must be approximately updated (diff) when adding an attached file
id93AP✅must be approximately updated (diff) when deleting an attached file
id5WO0✅must be approximately updated (diff) when deleting an event
[ACCO] account [AC04] /change-password
id6041✅must change the password to the given value
[ACCO] account [AC04] /change-password [APWD] When password rules are enabled [AC05] Complexity rules:
id1YPT✅must return an error if the new password is too short
id352R✅must accept the new password if it is long enough
id663A✅must return an error if the new password does not contains characters from enough categories
idOY2G✅must accept the new password if it contains characters from enough categories
[ACCO] account [AC04] /change-password [APWD] When password rules are enabled [AC06] Reuse rules:
idAFX4✅must return an error if the new password is found in the N last passwords used
id6XXP✅must accept the new password if different from the N last passwords used
[ACCO] account [AC04] /change-password [APWD] When password rules are enabled [AC07] Age rules:
idJ4O6✅must return an error if the current password’s age is below the set minimum
idRGGN✅must accept the new password if the current one’s age is greater than the set minimum
[ACCO] account [AC08] /request-password-reset and /reset-password
idG1VN✅“request” must trigger an email with a reset token, store that token, then “reset” must reset the password to the given value
idHV0V✅must not trigger a reset email if mailing is deactivated
idVZ1W✅must not trigger a reset email if reset mail is deactivated
id3P2N✅must not be possible to use a reset token to illegally change password of another user
idVGRT✅“reset” must return an error if the reset token was already used
[ACCO] account [AC08] /request-password-reset and /reset-password [RPWD] When password rules are enabled
idHZCU✅must fail if the new password does not comply (smoke test; see “/change-password” tests)
[PGTD] DELETE /users/:username [USAD] depending on "user-account:delete" config parameter
id8UT7✅Should accept when “personalToken” is active and a valid personal token is provided
idIJ5F✅Should reject when “personalToken” is active and an invalid token is provided
idNZ6G✅Should reject when only “personalToken” is active and a valid admin token is provided
idUK8H✅Should accept when “personalToken” and “adminToken” are active and a valid admin token is provided
[PGTD] DELETE /users/:username [DOA0] dnsLess:isActive = true [D7H0] when given existing username
idCM5Q✅should respond with 200
idBQXA✅should delete user entries from impacted collections
id4Y76✅should delete user event files
id75IW✅should delete HF data
idMPXH✅should delete user audit events
id635G✅should delete user from the cache
id710F✅should not delete entries of other users
idGUPH✅should not delete other user event files
[PGTD] DELETE /users/:username [DOA0] dnsLess:isActive = true [DL01] when given invalid authorization key
idJNVS✅should respond with 404
[PGTD] DELETE /users/:username [DOA0] dnsLess:isActive = true [DL02] when given not existing username
idC58U✅should respond with 404
[PGTD] DELETE /users/:username [DOA1] dnsLess:isActive = false [D7H1] when given existing username
idT21Z✅should respond with 200
idK4J1✅should delete user entries from impacted collections
idTIKT✅should delete user event files
id7WMG✅should delete HF data
idUWYY✅should delete user audit events
idU004✅should delete user from the cache
idWMMV✅should not delete entries of other users
id9ZTM✅should not delete other user event files
[PGTD] DELETE /users/:username [DOA1] dnsLess:isActive = false [DL01] when given invalid authorization key
idT3UK✅should respond with 404
[PGTD] DELETE /users/:username [DOA1] dnsLess:isActive = false [DL02] when given not existing username
idO73J✅should respond with 404
[PGTD] DELETE /users/:username [DL03] User - Create - Delete - Create - Login
idJBZM✅should be able to recreate this user, and login
[DYND] dynData [DYN01] ID generation
idDY01✅must generate unique IDs for each instance
idDY02✅must use provided prefix in IDs
idDY03✅must preserve stream hierarchy with correct parent references
idDY04✅must maintain access permissions with correct stream references
idDY05✅must preserve event streamIds with correct references
[DYND] dynData [DYN02] Data structure
idDY10✅must have same number of items as static data
idDY11✅must provide attachments (unchanged from static)
idDY12✅must provide helper functions
[DYND] dynData [DYN03] Reset functions
idDY20✅must reset users without error
idDY21✅must reset accesses without error
idDY22✅must reset profile without error
idDY23✅must reset streams without error
idDY24✅must reset events without error
idDY25✅must allow API access with dynamic user
[DYND] dynData [DYN04] Parallel isolation
idDY30✅must allow two instances to operate independently
[EVDY] events with dynData [EVDY01] GET /
idED01✅must return events for the user
idED02✅must filter events by streamIds
[EVDY] events with dynData [EVDY02] POST /
idED10✅must create a new event
[EVDY] events with dynData [EVDY03] GET /:id
idED20✅must return a specific event from dynData
[EVDY] events with dynData [EVDY04] Access with different tokens
idED30✅must return events with read-all access
idED31✅must restrict events with limited access
[MSTR] events.streamIds [MS01] events [MS02] GET /events
idWJ0S✅must return streamIds (if many)
[MSTR] events.streamIds [MS01] events [MS03] GET /events/:id
idIJQZ✅must return streamIds containing all stream IDs
[MSTR] events.streamIds [MS01] events [MS04] POST /events [MS06] when using "streamIds"
idVXMG✅must return streamIds containing all stream IDs
id2QZF✅must clean duplicate streamIds
idNY0E✅must forbid providing an unknown streamId
id6Z2D✅must forbid creating an event in multiple streams, if a contribute permission is missing on at least one stream
[MSTR] events.streamIds [MS01] events [MS07] PUT /events/:id
idBBBX✅must return streamIds containing all stream IDs
id42KZ✅must allow modification, if you have a contribute permission on at least 1 streamId
[MSTR] events.streamIds [MS01] events [MS07] PUT /events/:id [MS08] when modifying streamIds
idTQHG✅must forbid providing an unknown streamId
id6Q8B✅must allow streamId addition, if you have a contribute permission for it
idMFF7✅must forbid streamId addition, if you don’t have a contribute permission for it
id83N6✅must allow streamId deletion, if you have a contribute permission for it
idJLS5✅must forbid streamId deletion, if you have read but no contribute permission for it
[MSTR] events.streamIds [MS01] events [MS09] POST /event/start
idFOM3✅must return a 410 (Gone)
[MSTR] events.streamIds [MS01] events [MS10] POST /event/stop
idBR33✅must return a 410 (Gone)
[MSTR] events.streamIds [MS01] events [MS11] DELETE /events/:id
idBPL0✅must return streamIds containing all stream IDs
idT5ZY✅must allow trashing, if you have a contribute permission on at least 1 streamId
id2G32✅must allow deletion, if you have a contribute permission on at least 1 streamId
id6W5Y✅must forbid trashing, if you don’t have a contribute permission on at least 1 streamId
[MSTR] events.streamIds [MS01] events [MS12] GET /events/:id/:fileId -- attachments
idJNS8✅should retrieve the attachment with the app token
id6YFZ✅should retrieve the attachment with the app token correct headers
idNH1O✅should retrieve the attachment with the shared access readToken
id9KAF✅should retrieve the attachment with the shared access token
id9MEL✅should retrieve the attachment with the shared access readToken
[MSTR] events.streamIds [MS13] streams [MS14] POST /streams
idEGW2✅must forbid setting the “singleActivity” field
[MSTR] events.streamIds [MS13] streams [MS15] PUT /streams/:id
idEY79✅must forbid setting the “singleActivity” field
[MSTR] events.streamIds [MS13] streams [MS16] DELETE /streams [MS17] When the stream's event is part of at least another stream outside of its descendants [MS18] when mergeEventsWithParent=false
idTWDG✅must not delete events, but remove the deleted streamId from their streamIds
[MSTR] events.streamIds [MS13] streams [MS16] DELETE /streams [MS19] When the event is part of the stream and its children [MS20] when mergeEventsWithParent=false
id6SBU✅must delete the events
[MSTR] events.streamIds [MS13] streams [MS16] DELETE /streams [MS19] When the event is part of the stream and its children [MS21] when mergeEventsWithParent=true
id2FRR✅must not delete events, but remove all streamIds and add its parentId
[EVTP] Events (parallel) [ETP01] GET /events
idPTEV✅must return events for the user
idPT2V✅must filter events by stream
idPT3V✅must filter events by type
[EVTP] Events (parallel) [ETP02] POST /events
idPTC1✅must create an event
idPTC2✅must reject event with invalid stream
[EVTP] Events (parallel) [ETP03] PUT /events/:id
idPTU1✅must update an event
[EVTP] Events (parallel) [ETP04] DELETE /events/:id
idPTD1✅must trash an event
[EVPC] events (Pattern C) [EPC01] GET /
idPC01✅must return events
idPC02✅must only return events for the given streams when set
idPC03✅must return an error if some of the given streams do not exist
idPC04✅must only return events of any of the given types when set
idPC05✅must refuse unsupported event types
idPC06✅must only return events in the given time period
idPC07✅must take into account fromTime and toTime even if set to 0
idPC08✅must return only trashed events when requested
idPC09✅must return all events (trashed or not) when requested
idPC10✅must return only running period events when requested
idPC11✅must return an error if withDeletions is given as parameter
idPC12✅must only return events in the given paging range when set
[EVPC] events (Pattern C) [EPC02] POST /
idPC20✅must create an event with the sent data
idPC21✅must set the event time to “now” if missing
idPC22✅must accept explicit null for optional fields
idPC23✅must refuse events with no stream id
idPC24✅must return a correct error if an event with the same id already exists
idPC25✅must only allow ids that are formatted like cuids
idPC28✅must validate the event content if its type is known
idPC29✅must return an error if the sent data is badly formatted
idPC30✅must return an error if the associated stream is unknown
idPC31✅must return an error if the assigned stream is trashed
idPC32✅must not fail (500) when sending an array instead of an object
idPC33✅must not accept an empty streamIds array
idPC34✅must not fail when validating content if passing a string instead of an object
[EVPC] events (Pattern C) [EPC03] GET /
idPC40✅must return the event
idPC41✅must return an error if the event does not exist
[EVPC] events (Pattern C) [EPC04] PUT /
idPC50✅must modify the event with the sent data
idPC51✅must add/update/remove the specified client data fields without touching the others
idPC52✅must accept explicit null for optional fields
idPC53✅must validate the event content if its type is known
idPC54✅must return an error if the event does not exist
idPC55✅must return an error if the sent data is badly formatted
idPC56✅must return an error if the associated stream is unknown
[EVPC] events (Pattern C) [EPC05] DELETE /
idPC60✅must flag the event as trashed
idPC61✅must delete the event when already trashed
idPC62✅must return an error if event does not exist
[EVPC] events (Pattern C) [EPC07] Type wildcard support
idPC80✅must (unofficially) support a wildcard for event types
[EVPC] events (Pattern C) [EPC08] Deletions support
idPC90✅must include event deletions when requested
[EVNT] events [EV01] GET /
idWC8C✅must return the last 20 non-trashed events (sorted descending) by default
idU8U9✅must only return events for the given streams (incl. sub-streams) when set
idQR4I✅must only return events of any of the given types when set
idTWP8✅must (unofficially) support a wildcard for event types
id7MOU✅must only return events in the given time period sorted ascending when set
idW5IT✅must take into account fromTime and toTime even if set to 0
idY6SY✅must take into account modifiedSince even if set to 0
idQNDP✅must properly exclude period events completed before the given period
id5UFW✅must return ongoing events started before the given time period
idS9J4✅must only return events in the given paging range when set
id915E✅must return only trashed events when requested
id6H0Z✅must return all events (trashed or not) when requested
idJZYF✅must return only events modified since the given time when requested
idB766✅must include event deletions (since that time) when requested
idV72A✅must only return running period event(s) when requested
id68IL✅must return an error if no access token is provided
[EVNT] events [EV02] GET //
idF29M✅must return the attached file with the correct headers
idPP6G✅must return readToken in attachments
idNL65✅must accept a secure read token in the query string instead of the `“Authorization” header
idZDY4✅must accept special chars in Content-Disposition header
idTN27✅must allow a filename path suffix after the file id
idLOUB✅must allow any filename (including special characters)
id9NJ0✅must refuse an invalid file read token
id9HNM✅must refuse auth via the regular “auth” query string parameter
idMMCZ✅must return a proper error if trying to get an unknown attachment
[EVNT] events [EV03] POST /
id1GR6✅must create an event with the sent data, returning it
idWN86✅must return a correct error if an event with the same id already exists
id94PW✅must not allow reuse of deleted ids (unlike streams)
idUL6Y✅must not stop the running period event if the stream allows overlapping
id3S2T✅must allow the event’s period overlapping existing periods when the stream allows it
[EVNT] events [EV04] POST / (multipart content)
id4CUV✅must create a new event with the uploaded files
idHROI✅must properly handle part names containing special chars (e.g. “.”, “$”)
id0QGV✅must return an error if the non-file content part is not JSON
idR8ER✅must return an error if there is more than one non-file content part
[EVNT] events [EV05] POST / (multipart content)
idZI01✅must add the uploaded files to the event as attachments
idEUZM✅must add the uploaded files to the event without replacing existing attachments
[EVNT] events [EV06] GET /
id8GSS✅allows access at level=read
idIBO4✅denies access without authorization
[EVNT] events [EV07] PUT /
id4QRU✅must modify the event with the sent data
id6B05✅must add/update/remove the specified client data fields without touching the others
[EVNT] events [EV07] PUT / [EV08] forbidden updates of protected fields
idMPUA✅must prevent updating attachments
idL15U✅must prevent update of protected fields and throw a forbidden error in strict mode
id6NZ7✅must prevent update of protected fields and log a warning in non-strict mode
[EVNT] events [EV09] PUT HF/non-HF events
idZ7R1✅a normal event should not be updated to an hf-event
idZ7R2✅An hf-event should not be updated to a normal event
[EVNT] events [EV10] DELETE //
idRW8M✅must delete the attachment (reference in event + file)
idZLZN✅must return an error if not existing
[EVNT] events [EV11] DELETE /
idAT5Y✅must flag the event as trashed
id73CD✅must delete the event when already trashed including all its attachments
[EGSQ] events.get streams query [EQ01] Internal query helpers [EQ02] when transforming streams parameters
idD2B5✅must convert strings array to expanded array inside [{any: []}]
idJZWE✅must convert single string “B” to [{any: [“B”]}]
id8VV4✅must convert streams query with only “any” property to expanded streams query inside array [{any: []}])
idHFT2✅must convert streams query property “all” to "and: [{any…}, {any…}]) with each containing expanded streamIds
idPLMO✅must convert streams query property “all” to "and: [{any…}]) with each containing expanded streamIds
idJYUR✅must convert streams query property “all” and “not” to "and: [{any…}] not:) with each containing expanded streamIds
id2W2K✅must accept two streams queries expanding them
id2EF9✅must convert streams query {any: [“*”]} to [{any: [all accessible streams]}]
idTUZT✅must convert streams query {any: [*], not: [“A”]} to [{any: [all accessible streams], [expanded “A”]}]
idNHGF✅not accept any: "" query mixed with “all” query. like: {any: [], all: [“D”], not: [“A”]}
idU0FA✅not accept any: “*”, “B” mix. like: {any: ["*2, “D”], not: [“A”]}
idN3Q6✅must convert {any: “*”, not: [“A”]} to [{any: [all accessible streams], not: [expanded “A”]}]
[EGSQ] events.get streams query [EQ01] Internal query helpers [EQ02] when transforming streams parameters [EQ03] with multiple stores
idU6GS✅group query streamIds per store
idI7GF✅should throw an error if two different store are mixed in a query item
idZUTR❓should expand queries from differnt store
[EGSQ] events.get streams query [EQ01] Internal query helpers [EQ04] exception and errors
idIOLA✅must throw on malformed expressions
[EGSQ] events.get streams query [EQ01] Internal query helpers [EQ05] toMongoQuery()
idKKIH✅must convert to MongoDB including expansion
id4QMR✅must convert to MongoDB including with “ALL”
idNG7F✅must convert to MongoDB including expansion with “NOT”
idHC6X✅must convert to MongoDB including expansion with “ALL” and “NOT”
id0RNW✅must handle array of queries
[EGSQ] events.get streams query [EQ06] GET /events with streams queries
idNKH8✅must accept a simple string
idBW6Z✅must accept array of strings
idHFA2✅must accept * (star) with a not without including items in trashed streams
idMMB0✅must accept * (star) with !B && !E without including items in trashed streams
idVUER✅must return events in A && E
idCBP2✅must return events in A && !B
idI19H✅must return events in A && !D
id55HB✅must return events in A && NOT-EQUAL D
idO4DJ✅must return all events in B || (D && !E)
idUJSB✅must accept an object in a batch call (instead of a stringified one)
idENFE✅must accept a stringified object in a batch call
[EGSQ] events.get streams query [EQ06] GET /events with streams queries [EQ07] edge cases
idX8B1✅must return an error on non-existing stream
idWRVU✅must return error when there is no “any”
id30NV✅must return error when provided a boolean instead of a string
idYOJ9✅must return error when provided a null instead of a stream query
id8NNP✅must return an error when providing a non-stringified stream query
id3X9I✅must return an empty list when provided a trashed streamId
[FRBD] methods/helpers/commonFunctions.js: catchForbiddenUpdate(schema) [FB01] with streams schema
idDMGV✅must throw a forbidden error if “ignoreProtectedFieldUpdates” is null
idZ51K✅must throw a forbidden error if “ignoreProtectedFieldUpdates” is false
idEUKL✅must not throw any error if “ignoreProtectedFieldUpdates” is true but print a warn log
[FRBD] methods/helpers/commonFunctions.js: catchForbiddenUpdate(schema) [FB02] with events schema
id0RQM✅must throw a forbidden error if “ignoreProtectedFieldUpdates” is null
id6TK9✅must throw a forbidden error if “ignoreProtectedFieldUpdates” is false
idIJ4M✅must not throw any error if “ignoreProtectedFieldUpdates” is true but print a warn log
[FRBD] methods/helpers/commonFunctions.js: catchForbiddenUpdate(schema) [FB03] with accesses schema
idGP6C✅must throw a forbidden error if “ignoreProtectedFieldUpdates” is null
idMUC0✅must throw a forbidden error if “ignoreProtectedFieldUpdates” is false
idQGDA✅must not throw any error if “ignoreProtectedFieldUpdates” is true but print a warn log
[AUTHP] auth (parallel) [AUP01] /login
idP2CV✅must authenticate credentials and return access token
idP1TI✅must not be case-sensitive for the username
idPL7J✅must return error when credentials are invalid
idP4AQ✅must return error if app id is untrusted
idPNDB✅must return error if origin does not match app id
idP5UM✅must reuse session if already open
[AUTHP] auth (parallel) [AUP02] /logout
idP6W5✅must terminate session and fail second logout
[AUTH] auth [AU01] /login
id2CV5✅must authenticate the given credentials, open a session and return the access token
id68SH✅must return expired
id5UMP✅must reuse the current session if already open
id509A✅must accept “wildcarded” app ids and origins
idADL4✅must accept “no origin” (i.e. not a CORS request) if authorized
idA7JL✅must also accept “referer” in place of “origin” (e.g. some browsers do not provide “origin”)
idIKNM✅must also accept “referer” in place of “origin” (e.g. some browsers do not provide “origin”)
id1TI6✅must not be case-sensitive for the username
idFMJH✅must support concurrent login request, saving only the last token that is written in the storage
id9WHP✅must not leak _private object from Result
[AUTH] auth [AU01] /login [AU02] when we log into a temporary log file
idC03J✅must replace the password in the logs by (hidden) when an error occurs
idG0YT✅must not mention the password in the logs when none is provided
[AUTH] auth [AU01] /login [WPRA] When password rules are enabled
id675V✅must succeed if the password is not yet expired, returning planned expiration time and possible change time
idD3EV✅must return an error if the password has expired, indicating the date it did so
[AUTH] auth [AU03] /logout
id6W5M✅must terminate the access session and fail to logout a second time (session already expired)
idE2MD✅(or any request) must alternatively accept the access token in the query string
[AUTH] auth [AU04] SSO support
idTIDW✅GET /who-am-i must return a 410 as it has been removed
[MAIL] Mailing helper methods
idHGVD✅should throw an error if mailing method is invalid
idOKQ2✅should throw an error if mailing method is missing
[MAIL] Mailing helper methods [ML01] using Mandrill [ML02] validating request body
idGU60✅should not be empty
id8JJU✅should contain a valid auth key
idG906✅should contain a valid recipient
idKBE0✅should contain a valid substitution of variables
id2ABY✅should contain valid tags
[MAIL] Mailing helper methods [ML03] using Microservice [ML04] validating request body
idLHCB✅should not be empty
id9UEU✅should contain a valid auth key
id1Y6K✅should contain a valid recipient
idUT8M✅should contain a valid substitution of variables
[ARSR] ArraySerializationStream [AR01] testing around the array size limit
idU21Z✅must return a valid array when receiving limit-3 items
idMKNL✅must return a valid array when receiving limit-2 items
idMUPF✅must return a valid array when receiving limit-1 items
idCM4Q✅must return a valid array when receiving limit+0 items
idF8S9✅must return a valid array when receiving limit+1 items
id6T4V✅must return a valid array when receiving limit+2 items
idQBOS✅must return a valid array when receiving limit+3 items
[ARSR] ArraySerializationStream [AR02] testing with small number of items
id69F6✅must return a valid array when receiving 0 item(s)
idBJRT✅must return a valid array when receiving 1 item(s)
idYJI0✅must return a valid array when receiving 2 item(s)
idEKQQ✅must return a valid array when receiving 3 item(s)
[DRNM] DrainStream
idAFWR✅must be fed objects and return them in the callback
id23UQ✅must return an error when the provided limit is exceeded
[MFAA] MFA acceptance (seq) [MA1] when services.mfa.mode is "disabled" (default)
idMA1A✅auth.login returns the access token directly
idMA1B✅mfa.activate returns 503 (apiUnavailable)
[MFAA] MFA acceptance (seq) [MA2] when services.mfa.mode is "challenge-verify" [MA3] mfa.activate
idMA3A✅sends an SMS challenge and returns a 302 with mfaToken
idMA3B✅rejects an app-type access token with 403
idMA3C✅propagates an SMS provider error as 400
[MFAA] MFA acceptance (seq) [MA2] when services.mfa.mode is "challenge-verify" [MA4] mfa.confirm
idMA4A✅verifies the code, persists profile.mfa, returns 10 recovery codes
idMA4B✅rejects an invalid mfaToken with 401
idMA4C✅propagates an SMS verify error as 400
[MFAA] MFA acceptance (seq) [MA2] when services.mfa.mode is "challenge-verify" [MA5] auth.login + mfa.verify after MFA activation
idMA5A✅mfa.verify with a valid code releases the real Pryv access token
idMA5B✅mfa.challenge re-sends the SMS during a pending login
idMA5C✅mfa.verify with a bogus mfaToken returns 401
[MFAA] MFA acceptance (seq) [MA2] when services.mfa.mode is "challenge-verify" [MA6] mfa.deactivate
idMA6A✅clears the MFA profile; subsequent login returns a real token
[MFAA] MFA acceptance (seq) [MA2] when services.mfa.mode is "challenge-verify" [MA7] mfa.recover
idMA7A✅disables MFA when called with a valid recovery code
idMA7B✅rejects an invalid recovery code
idMA7C✅rejects when password is wrong
[PCRO] permissions create-only level [PC01] Permissions - create-only level [PC02] Accesses [PC07] GET / [PC08] when using an access with a "create-only" permissions
idHOTO✅should return an empty list
[PCRO] permissions create-only level [PC01] Permissions - create-only level [PC02] Accesses [PC09] POST / [PC10] when using an access with a "create-only" permission
idX4Z1✅a masterToken should allow to create an access with a “create-only” permissions
idATCO✅an appToken with managed rights should allow to create an access with a “create-only” permissions
idATCY✅an appToken with managed rights should allow to create an access with a “create-only” permissions and selfRevoke forbidden
idATCR✅an appToken with read rights should be forbidden to create an access with a “create-only” permissions
idATCC✅an appToken with contribute rights should be allowed to create an access with a “create-only” permissions
idFEGI✅a createOnlyToken should forbid to create an access with a “read” level permission permission
idSL4P✅should forbid to create an access with a “contribute” level permission
idZX1M✅should forbid to create an access with a “manage” level permission
[PCRO] permissions create-only level [PC01] Permissions - create-only level [PC02] Accesses [PC11] PUT /
id1WXJ✅should forbid updating accesses
[PCRO] permissions create-only level [PC01] Permissions - create-only level [PC02] Accesses [PC12] DELETE /
idG6IP✅should forbid deleting accesses
[PCRO] permissions create-only level [PC03] Events [PC13] GET /
idCKF3✅should return an error list when fetching explicitly “create-only” streams
idV4KJ✅should not return events when fetching “create-only” streams that are children of “read” streams
idSYRW✅should not return events when fetching “create-only” streams that are children of “contribute” streams
[PCRO] permissions create-only level [PC03] Events [PC14] GET /:id
idN61I✅should forbid fetching an event when using a “create-only” permission
[PCRO] permissions create-only level [PC03] Events [PC15] POST /
id0G8I✅should forbid creating events for out of scope streams
idF406✅should allow creating events for “create-only” streams
[PCRO] permissions create-only level [PC03] Events [PC16] PUT /
idV0UO✅should forbid updating events for “create-only” streams
[PCRO] permissions create-only level [PC03] Events [PC17] DELETE /
id5OUT✅should forbid deleting events for “create-only” streams
[PCRO] permissions create-only level [PC03] Events [PC04] attachments [PC18] GET /events/{id}/{fileId}[/{fileName}]
idVTU4✅should be forbidden
[PCRO] permissions create-only level [PC03] Events [PC04] attachments [PC19] POST /events/{id}
id8J8O✅should be forbidden
[PCRO] permissions create-only level [PC03] Events [PC04] attachments [PC20] DELETE /events/{id}/{fileId}
idGY6M✅should be forbidden
[PCRO] permissions create-only level [PC05] Streams [PC21] GET /
idJ12F✅should only return streams for which permissions are defined
[PCRO] permissions create-only level [PC05] Streams [PC22] POST /
idTFWF✅should forbid creating child streams in “create-only” streams
[PCRO] permissions create-only level [PC05] Streams [PC23] PUT /
idPCO8✅should forbid updating “create-only” streams
[PCRO] permissions create-only level [PC05] Streams [PC24] DELETE /
idPCO9✅should forbid deleting “create-only” streams
[PCRO] permissions create-only level [PC06] Webhooks [PC25] CREATE /
id3AE9✅should allow creating webhooks
[PFRC] permissions forcedStreams [PF01] GET /events with forcedStreams
idSO2E✅must not see events on “B” when querying *
idELFF✅must refuse querying C
[PNON] permissions none [PN01] GET /events with none permissions
idVVOA✅must not see event in “none” level stream
[PSLF] permissions selfRevoke [PS01] POST /accesses
idJYL5✅must list accesses with forbidden selfRevoke by GET /accesses
idJYU5✅must forbid creating accesses with selfRevoke different than forbidden
idUZRA✅an appToken with managed rights should allow to create an access with selfRevoke forbidden
[PSLF] permissions selfRevoke [DACC] DELETE /accesses
idAHS6✅must allow app accesses to self revoke by default
idH6DU✅must forbid app accesses to self revoke when set
id3DR7✅must allow shared accesses to self revoke by default
idF62D✅must forbid shared accesses to self revoke when set
[ACCP] Access permissions (sequential) [AP03] Auth and change tracking [AP04] custom auth step (e.g. to validate/parse caller id)
idIA9K✅must be supported and deny access when failing
idH58R✅must allow access when successful
idH58Z✅must allow access whith “callerid” headers
idISE4✅must fail properly (i.e. not granting access) when the custom function crashes
idP4OM✅must validate the custom function at startup time
[PPERM] Access permissions (Pattern C) [AP01] Events
id1AK1✅get must only return events in accessible streams
idNKI5✅get must return all events when permissions are defined for “all streams” (*)
id5360✅get must alternatively accept the access token in the query string
idKTM1✅must forbid getting an attached file if permissions are insufficient
id2773✅must forbid creating events for ‘read-only’ streams
idZKZZ✅must forbid updating events for ‘read-only’ streams
id4H62✅must forbid deleting events for ‘read-only’ streams
idY38T✅must allow creating events for ‘contribute’ streams
[PPERM] Access permissions (Pattern C) [AP02] Streams
idBSFP✅get must only return streams for which permissions are defined
idR4IA✅must forbid creating child streams in ‘read-only’ streams
idKHI7✅must forbid creating child streams in ‘contribute’ streams
idMCDP✅must forbid deleting child streams in ‘contribute’ streams
id7B6P✅must forbid updating ‘contribute’ streams
idRG5R✅must forbid deleting ‘contribute’ streams
id21AZ✅must not allow creating child streams in trashed ‘managed’ streams
idO1AZ✅must allow creating child streams in ‘managed’ streams
id5QPU✅must forbid moving streams into non-‘managed’ parent streams
idHHSS✅must recursively apply permissions to the streams’ child streams
idNJ1A✅must allow access to all streams when no specific stream permissions are defined
idKP1Q✅must allow deleting child streams in ‘managed’ streams
[PPERM] Access permissions (Pattern C) [AP03] Auth and change tracking
idYE49✅must handle optional caller id in auth (in addition to token)
[PRFA] profile (app) [PA01] GET /public
idFWG1✅must return publicly shared key-value profile info
[PRFA] profile (app) [PA02] GET /app
id13DL✅must return key-value settings for the current app
idJ37U✅must refuse requests with a shared access token
idGYBN✅must refuse requests with a personal access token
[PRFA] profile (app) [PA03] PUT /app
id1QFB✅must add/update/remove the specified keys without touching the others
id0H9A✅must refuse requests with a shared access token
idJC5F✅must refuse requests with a personal access token
[PRFP] profile (personal) [PP01] GET
idJ61R✅/public must return publicly shared key-value profile info
idHIMS✅/private must return private key-value profile info
id36B1✅must return an appropriate error for other paths
idFUJA✅“private” must be forbidden to non-personal accesses
[PRFP] profile (personal) [PP02] PUT
idM28R✅/public must add/update/remove the specified keys without touching the others
idWU9C✅/private must add/update/remove the specified keys without touching the others
id2AS6✅must create the profile if not existing
idQ99E✅must return an appropriate error for other paths
idT565✅must be forbidden to non-personal accesses
[RG2C] Two-core integration tests Core startup verification
id2C01❓both cores must respond to HTTP requests
id2C02❓both cores must share the same PlatformDB
[RG2C] Two-core integration tests Registration + PlatformDB replication
id2C10❓must register a user on Core A
id2C11❓Core B must see the user via /reg/cores lookup
id2C12❓admin/users on Core A must list the user
[RG2C] Two-core integration tests DNS resolution
id2C20❓DNS must resolve username to correct core IP
id2C21❓DNS must resolve lsc.{domain} to all core IPs
[RG2C] Two-core integration tests Admin endpoints across cores
id2C30❓/system/admin/cores must list both cores
id2C31❓/reg/hostings must reflect available cores
[RGAC] Register access authorization POST /reg/access
idRA01✅must create an access request and return polling key
idRA02✅must return 400 for missing requestingAppId
idRA03✅must return 400 for missing requestedPermissions
idRA04✅must echo clientData and oauthState
[RGAC] Register access authorization GET /reg/access/:key
idRA10✅must return current state for valid key
idRA11✅must return 400 for unknown key
[RGAC] Register access authorization POST /reg/access/:key (accept)
idRA20✅must accept and return token + apiEndpoint
idRA21✅subsequent poll must return ACCEPTED state
idRA22✅must return 400 for ACCEPTED without token
[RGAC] Register access authorization POST /reg/access/:key (refuse)
idRA30✅must refuse with reason
idRA31✅subsequent poll must return REFUSED state
[RGAC] Register access authorization POST /reg/access/:key (errors)
idRA40✅must return 400 for invalid status
idRA41✅must return 400 for unknown key
[RGGF] Register gap features GET /:username/service/infos (alias)
idGF01✅must return same status and structure as /service/info
[RGGF] Register gap features GET /apps
idGF10✅must return apps list (may be empty)
idGF11✅must return 404 for unknown appid
[RGGF] Register gap features POST /access/invitationtoken/check
idGF20✅must return true when invitationTokens config is null (allow all)
idGF21✅must return false for invalid token when tokens are configured
[RGGF] Register gap features DELETE /system/users/:username
idGF30✅must require onlyReg=true
idGF31✅must support dryRun without deleting
idGF32✅must return 404 for unknown user
idGF33✅must reject without admin auth
[RGGF] Register gap features POST /system/users/validate
idGF40✅must validate and reserve unique fields for new user
idGF41✅must reject duplicate username
idGF42✅must reject invalid invitation token
idGF43✅must reject without admin auth
[RGGF] Register gap features PUT /system/users
idGF50✅must update user fields
idGF51✅must reject without username
idGF52✅must reject without admin auth
[RGLG] Legacy register routes + invitations GET /reg/:email/username
idLG01✅must return username for known email
idLG02✅must return 404 for unknown email
[RGLG] Legacy register routes + invitations GET /reg/:email/uid (deprecated)
idLG03✅must return uid for known email
[RGLG] Legacy register routes + invitations GET /reg/:uid/server
idLG10✅must redirect for known user
idLG11✅must return 404 for unknown user
[RGLG] Legacy register routes + invitations POST /reg/:uid/server
idLG12✅must return server and alias for known user
idLG13✅must return 404 for unknown user
[RGLG] Legacy register routes + invitations GET /reg/admin/users/:username
idLG20✅must return user info with admin auth
idLG21✅must return 404 for unknown user
idLG22✅must reject without admin auth
[RGLG] Legacy register routes + invitations GET /reg/admin/servers
idLG30✅must return servers object with admin auth
[RGLG] Legacy register routes + invitations GET /reg/admin/invitations
idLG40✅must return invitations list with admin auth
[RGLG] Legacy register routes + invitations GET /reg/admin/invitations/post
idLG41✅must generate invitation tokens
idLG42✅generated tokens must appear in invitations list
idLG43✅generated tokens must be valid for registration check
idLG44✅must reject without admin auth
[RGMC] register: multi-core [MC01] registration redirect
idMC01A✅must return redirect when user is assigned to another core
idMC01B✅must assign user-to-core mapping in PlatformDB
[RGMC] register: multi-core [MC02] GET /reg/cores multi-core
idMC02A✅must return the correct core URL for a mapped user
idMC02B✅must return error for unknown username
[RGMC] register: multi-core [MC03] GET /reg/hostings multi-core
idMC03A✅must return hostings with availability from PlatformDB
[RGMC] register: multi-core [MC04] /reg/access REDIRECTED
idMC04A✅must accept REDIRECTED status with redirectUrl
idMC04B✅poll must return REDIRECTED with new poll URL
idMC04C✅must return 400 for REDIRECTED without redirectUrl
[RGMC] register: multi-core [MC05] selectCoreForRegistration
idMC05A✅must return core with fewest users
idMC05B✅must filter by hosting
idMC05C✅must fall back to self when no candidates match hosting
idMC05D✅single-core always returns self
[RGMC] register: multi-core [MC06] setAvailable
idMC06A✅must exclude unavailable core from registration selection
idMC06B✅setAvailable(false) must update own core info
[RGMC] register: multi-core [MC07] GET /system/admin/cores
idMC07A✅must list cores with user counts
[RGMC] register: multi-core [MC08] coreIdToUrl
idMC08A✅must derive URL from coreId + domain
idMC08B✅must return own URL when no domain (single-core fallback)
[RGMC] register: multi-core [MC09] wrong-core middleware
idMC09A✅must return 421 wrong-core when user is hosted on a different core
idMC09B✅must let through requests for users hosted on this core
idMC09C✅must let through requests for unknown users (no PlatformDB mapping)
idMC09D✅must skip /reg and /system routes
idMC09E✅single-core mode must be a no-op
[RGMC] register: multi-core [MC10] core.url override
idMC10A✅coreIdToUrl must return the explicit URL when other core has core.url set
idMC10B✅coreIdToUrl must fall back to derivation when no explicit URL is registered
idMC10C✅wrong-core middleware must surface explicit URL in 421 response
[RGRC] Register records admin endpoint POST /reg/records
idRR01✅must accept valid record update with admin auth
idRR02✅must reject request without admin auth
idRR03✅must reject request with wrong admin key
idRR04✅must reject request with missing subdomain
idRR05✅must reject request with missing records
idRR06✅record must persist to PlatformDB and overwrite cleanly
[REGC] registration: cluster [RC01] POST /users (create user) [RC01A] successful registration
idQV8Z✅should respond with status 201
idTCOM✅should respond with the username and apiEndpoint
[REGC] registration: cluster [RC01] POST /users (create user) [RC03] when the username already exists
idNUC9✅should respond with status 409
idX1IA✅should respond with the correct error
[REGC] registration: cluster [RC01] POST /users (create user) [RC04] when the email already exists
idSJXN✅should respond with status 409
idU0ZN✅should respond with the correct error
[REGC] registration: cluster [RC01] POST /users (create user) [RC05] when the username and email both exist
idLUC6✅should respond with status 409
idXIN8✅should respond with the correct error
[REGC] registration: cluster [RC01] POST /users (create user) [RC07] when invitationTokens are undefined (null) [RC08] and a random string is provided as "invitationToken"
idCMOV✅should respond with status 201
[REGC] registration: cluster [RC01] POST /users (create user) [RC07] when invitationTokens are undefined (null) [RC09] and "invitationToken" is missing
idLOIB✅should respond with status 201
[REGC] registration: cluster [RC01] POST /users (create user) [RC10] when invitationTokens are defined [RC11] when a valid one is provided
idZ2ZY✅should respond with status 201
id1BF3✅should find password in password history
[REGC] registration: cluster [RC01] POST /users (create user) [RC10] when invitationTokens are defined [RC12] when an invalid one is provided
id4GON✅should respond with status 400
idP4GT✅should respond with the correct error message
[REGC] registration: cluster [RC01] POST /users (create user) [RC13] when invitationTokens are set to [] (forbidden creation) [RC14] when any string is provided
idCX9N✅should respond with status 400
[REGC] registration: cluster [RC01] POST /users (create user) [RC15] when custom account streams validation exists [RC16] when email is set as required and it is not set in the request
idUMWB✅should respond with status 400
id8RDA✅should respond with the correct error
[REGC] registration: cluster [RC01] POST /users (create user) [RC15] when custom account streams validation exists [RC17] when field does not match custom validation settings
id8W22✅should respond with status 400
idGBKD✅should respond with the correct error
[REGC] registration: cluster [RC01] POST /users (create user) [RCPW] When password rules are enabled
id0OBL✅must fail if the new password does not comply
id5BQL✅must succeed if the new password complies
[BMM2] registration: DNS-less [RD01] POST /users
idKB3T✅should respond with status 201 when given valid input
idVDA8✅should respond with correct apiEndpoint for valid registration
idLPLP✅Valid access token exists in the response
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD03] when given an invalid username parameter [3Q1H] that is too short
idM6CD✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD03] when given an invalid username parameter [MST7] that is too long
idTL2W✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD03] when given an invalid username parameter [XTD0] that has invalid characters
idEIKE✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD04] when given an invalid password parameter [FSE9] that is too short
idOYZM✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD04] when given an invalid password parameter [LQWX] that is too long
idSBCX✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD04] when given an invalid password parameter [T56V] that has an invalid type
idMP5F✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD05] when given an invalid email parameter [S8U8] that is too long
id1JN8✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD05] when given an invalid email parameter [6OX5] that has an invalid type
id6SID✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD06] when given an invalid appId parameter [5P2E] that is too short
idI9QE✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD06] when given an invalid appId parameter [HI9V] that is too long
id4XCV✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD06] when given an invalid appId parameter [K4LE] that has an invalid type
idNZ4J✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD07] when given an invalid invitationToken parameter [CYW6] that has an invalid type
id79A5✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD08] when given an invalid referer parameter [5BNJ] that is too long
idV51E✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD08] when given an invalid referer parameter [AFUH] that has an invalid type
idC4PK✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD09] when given an invalid language parameter [UPWY] that is too short
idQYT8✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD09] when given an invalid language parameter [LP4S] that is too long
idR1LT✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD02] Schema validation [RD09] when given an invalid language parameter [RHT6] that has an invalid type
id0QGW✅should respond with status 400 and correct error message
[BMM2] registration: DNS-less [RD01] POST /users [RD10] Property values uniqueness
idLZ1K✅should respond with status 409 and correct error for duplicate username/email
[BMM2] registration: DNS-less [RD01] POST /users [RD11] When providing an indexed value that is neither a number nor a string
idS6PS✅must return an error when providing an object
[BMM2] registration: DNS-less [RD12] GET /reg/:username/check
id7T9L✅when checking a valid available username, it should respond with status 200 and {reserved:false}
id153Q✅when checking a valid taken username, it should respond with status 200 and reserved:true
idH09H✅when checking a too short username, it should respond with status 400 and the correct error
idVFE1✅when checking a too long username, it should respond with status 400 and the correct error
idFDTC✅when checking a username with invalid characters, it should respond with status 400 and the correct error
[EVST] events streaming with 2000 entries
idSE1K✅Streams events
idXZGB✅Streams deleted in sent as chunked
[RSLT] Result [RS01] concatStream
id36RQ✅must concatenate multiple streams in a single Array
[RSLT] Result [RS02] toObject()
idNKHF✅must return the result’s content when not storing streams
idMHAS✅must return the result content when storing streams
id6P4Z✅must return an error object when attempting to serialize streams containing an amountof objects exceeding the limit
idTTEL✅must return an error when storing piped streams
idH2GC❓must return an error when the core pipeline crashes because of size
[ROOT] root [RT01] GET /
idUA7B✅should return basic server meta information as JSON when requested
idTO50✅should return basic server meta information as text otherwise
idTS3D✅should return an error if trying to access an unknown user account
[ROOT] root [RT02] All requests:
idTJHO✅should return correct common HTTP headers + meta data in response body
idOQ3G✅should return meta data in response body for errors as well
idP06Y✅should properly translate the Host header’s username (i.e. subdomain)
idR3H5✅should translate the username in subdomain also when it only contains numbers
id5IQK✅should support POSTing “urlencoded” content with _json and _auth fields
id2YEI✅should support POSTing “urlencoded” content with _json, _method (PUT) and _auth fields
idVJTP✅should support POSTing “urlencoded” content with _json, _method (DELETE) and _auth fields
id6D5O✅should properly handle JSON errors when POSTing “urlencoded” content with _json field
idJ2WP✅trackingFunctions should update the access’s “last used” time and internal request counters
[ROOT] root [RT03] OPTIONS /
idPDMA✅should return OK
[ROOT] root [RT04] GET /access-info
id0MI8✅must return current access information
[ROOT] root [RT05] Accept Basic Auth request
id0MI9✅must accept the https://token@user.domain/ AUTH schema
id0MI0✅must accept the https://token:anystring@user.domain/ AUTH schema
id3W3Y✅must accept the https://token:@user.domain/ AUTH schema
idM54U✅must return a 401 error when basic auth is missing using https://@user.domain/
idTPH4✅must return a 403 error when using https://:token@user.domain/
[ROOT] root [RT06] POST / (i.e. batch call)
id2IV3✅must be able to create streams with non-star permissions access
idORT3✅must execute the given method calls and return the results
idTVPI✅must execute the method calls containing events.get and return the results
idU4RB✅should not add a null meta field in the response
idWGVY✅must return an error if the sent data is badly formatted
idTV17✅streamed results such as stream.delete should be serialiazed
[SINF] Service [SN01] GET /service/info
idFR4K✅must return all service info
[SK01] Socket.IO
id25M0✅must dynamically create a namespace for the user
id9ZH8✅must send correct CORS headers
idVGKX✅must connect with twice user name in the path (DnsLess)
idVGKH✅must connect to a user with a dash in the username
idOSOT✅must refuse connection if no valid access token is provided
[SK01] Socket.IO [SK02] calling API methods
idFI6F✅must properly route method call messages for events and return the results, including meta
idO3SW✅must properly route method call messages for streams and return the results
idTO6Z✅must accept streamQuery as Javascript Object
idNGUZ✅must not crash when callers omit the callback
idACA3✅must fail if the called target does not exist
idL8WJ✅must fail if the called method does not exist
idSNCW✅must return API errors properly, including meta
id744Z✅must notify other sockets for the same user about events changes
idGJLT✅must notify other sockets for the same user (only) about streams changes
idJC99✅must notify on each change
[SK01] Socket.IO [SK03] when using an access with a "create-only" permission
idK2OO✅must allow a connection
[SK01] Socket.IO [SK04] when spawning 2 api-server processes, A and B
idJJRA❓changes made in A notify clients of B
[STRP] streams (Pattern C) [STP01] GET /
idP7G8✅must return streams
idP7G9✅must return streams with state=all
idPAJZ✅must return a correct error if the parent stream is unknown
idPG5F✅must return a correct error if the stream is unknown
[STRP] streams (Pattern C) [STP02] POST /
idPENV✅must create a new root stream with the sent data and notify
idPA2H✅must return a correct error if the sent data is badly formatted
idPGGS✅must return a correct error if a stream with the same id already exists
idP8WG✅must accept explicit null for optional fields
idP88V✅must return an error if the new stream’s parentId is empty string
idP84R✅must slugify the new stream’s predefined id
idP2B3✅must return a correct error if the parent stream is unknown
idP8JB✅must return a correct error if the given predefined stream’s id is “null”
idP6TP✅must return a correct error if the given predefined stream’s id is “*”
idPZ3R✅must accept streamId “size”
idPCHD✅must create a child stream when providing a parent stream id and notify
idPJIN✅must return a correct error if the sent data is not valid JSON
[STRP] streams (Pattern C) [STP03] PUT /
idPSO4✅must modify the stream with the sent data and notify
idP5KN✅must accept explicit null for optional fields
idPPL2✅must return a correct error if the stream does not exist
idPJWT✅must return a correct error if the sent data is badly formatted
idPHJB✅must return a correct error if the new parent stream is unknown
idP29S✅must return an error if the parentId is the same as the id
[STRP] streams (Pattern C) [STP04] DELETE /
idP205✅must flag the specified stream as trashed and notify
idP1U1✅must return a correct error if the item is unknown
[STRP] streams (Pattern C) [STP05] Sibling name conflicts
idPNRS✅must fail if a sibling stream with the same name already exists
[STRE] streams [ST01] GET /
idTG78✅must return non-trashed streams (as a tree) by default
idDPWG✅must return all streams (trashed or not) when requested
idRDD5✅must include stream deletions (since the given time) when requested
idT8AM✅must include stream deletions even when the given time is 0
id1M8A❓must not keep stream deletions past a certain time (cannot test because cannot force-run Mongo’s TTL cleanup task)
idW9VC✅must return a correct 401 error if no access token is provided
idUVWK✅must return child streams when providing a parent stream id
[STRE] streams [ST02] POST /
idUHKI✅must allow reuse of deleted ids
idJINC✅must return a correct error if the sent data is not valid JSON
[STRE] streams [ST03] PUT /
id344I✅must fail if a sibling stream with the same name already exists
idJT6G✅must modify the stream with the sent data event if name and parentId sent are the same
idPT1E✅must move the stream under the given parent when specified
[STRE] streams [ST03] PUT / [ST04] forbidden updates of protected fields
idPN1H✅must fail and throw a forbidden error in strict mode
idA3WC✅must succeed by ignoring protected fields and log a warning in non-strict mode
[STRE] streams [STRD] DELETE /
idTEFF✅must delete the stream when already trashed with its descendants if there are no linked events
idLVTR✅must return a correct error if there are linked events and the related parameter is missing
idRKEU✅must reject the deletion of a root stream with mergeEventsWithParent=true
id26V0✅must reassign the linked events to the deleted stream’s parent when specified
idKLD8✅must delete the linked events when mergeEventsWithParent is false
[SYRO] system route
idJT1A✅should parse correctly usernames starting with “system”
idCHEK✅System check Platform integrity
[SYRO] system route [SY01] DELETE /mfa
id1V4D✅should return 204
id3HE9✅should delete the user’s “mfa” profile property
idI2PU✅should not delete anything else in the profile
[SYER] system (ex-register) [SY02] POST /create-user (DEPRECATED)
id0G7C✅must not send a welcome email if mailing is deactivated
idTWBF✅must not send a welcome email if welcome mail is deactivated
[SYER] system (ex-register) [SY02] POST /create-user (DEPRECATED) [SY03] when email sending really works
idFUTR✅must create a new user with the sent data, sending a welcome email
[SYER] system (ex-register) [SY02] POST /create-user (DEPRECATED) [SY04] when it just replies OK
id9K71✅must run the process but not save anything for test username “backloop”
idVGF5✅must return a correct 400 error if the sent data is badly formatted
idABI5✅must return a correct 400 error if the language property is above 5 characters
idOVI4✅must return a correct 400 error if the language property is the empty string
idRD10✅must return a correct 400 error if a user with the same user name already exists
idNPJE✅must return a correct 400 error if a user with the same email address already exists
idY5JB✅must return a correct 404 error when authentication is invalid
idGF3L✅must return a correct error if the content type is wrong
[SYER] system (ex-register) [SY02] POST /create-user (DEPRECATED) [SY05] when we log into a temporary log file
idY69B✅must replace the passwordHash in the logs by (hidden) when the authentication is invalid
idMEJ9✅must replace the passwordHash in the logs by (hidden) when the payload is invalid (here parameters)
idCO6H✅must not mention the passwordHash in the logs when none is provided
[SYER] system (ex-register) [SY06] GET /user-info/{username}
id9C1A✅trackingFunctions must return user information (including time of last account use)
idFNJ5✅must return a correct 404 error when authentication is invalid
[SSDC] SystemStreams config [SD01] when valid custom systemStreams are provided
idGB8G✅must set default values and other fields
idKMT3✅must prefix default streams with the Pryv prefix
idPVDC✅must prefix custom streams with the customer prefix
[SSDC] SystemStreams config [SD03] When custom system streams contain duplicate streamIds
idCHEF✅must throw a config error
[SSDC] SystemStreams config [SD04] When providing a custom system stream that is unique but not indexed
id42A1✅must throw a config error
[SSDC] SystemStreams config [SD05] When providing a custom system stream that has an invalid type
idLU0A❓must throw a config error
[SSDC] SystemStreams config [SD06] When providing an "other" custom stream that is unique
idGZEK✅must throw a config error
[SSDC] SystemStreams config [SD07] When providing an "other" custom stream that is indexed
id2IBL✅must throw a config error
[SSDC] SystemStreams config [SD08] When providing an "other" custom stream that is non editable
id655X✅must throw a config error
[SSDC] SystemStreams config [SD09] When providing an "other" custom stream that is required at registration
idOJJ0✅must throw a config error
[SVIF] config: serviceInfo [SI01] when dnsLess is disabled [SI02] when "serviceInfoUrl" points to a file
idD2P7✅should load serviceInfo
[UPLD] uploads middleware [UP01] hasFileUpload
idGY5H✅should parse file uploads
[NOTF] Notifications [NF01] #serverReady
idB76G✅notifies internal listeners
idSRAU✅notifies test listeners
[NOTF] Notifications [NF02] #accountChanged
idP6ZD✅notifies internal listeners
idQ96S✅notifies test listeners
[NOTF] Notifications [NF03] #accessesChanged
idP5CG✅notifies internal listeners
idVSN6✅notifies test listeners
[NOTF] Notifications [NF05] #streamsChanged
idLDUQ✅notifies internal listeners
idBUR1✅notifies test listeners
[NOTF] Notifications [NF06] #eventsChanged
idN8RI✅notifies internal listeners
idTRMW✅notifies test listeners
[AUTN] Authentication [AT01] hasProperties
idIKAI✅returns true if all properties exist
idK2PZ✅returns false if not all properties exist
idU2NA✅returns false if null is given
idWJ7J✅returns false if a string is given
[CSVL] tryCoerceStringValues
idDTZ1✅should behave as documented in the method
idX26S✅doesn’t create keys in object
id4MHH✅should convert to array
idX8PY✅number conversion works
[VERS] Versioning [VE01] Events
idRWIA✅must not return history when calling events.get
[VERS] Versioning [VE01] Events [VE02] deletionMode
idFLLW✅must delete the event’s history when deleting it with deletionMode=keep-nothing
id6W0B✅must minimize the event’s history when deleting it with deletionMode=keep-authors
id1DBC✅must not modify the event’s history when deleting it with deletionMode=keep-everything
[VERS] Versioning [VE01] Events [VE03] events.getOne
idYRI7✅must not return an event’s history when calling getOne with includeHistory flag off
idKPQZ✅must return an event’s history when calling getOne with includeHistory flag on
[VERS] Versioning [VE01] Events [VE04] forceKeepHistory is OFF
idPKA9✅must not generate history when updating an event
[VERS] Versioning [VE01] Events [VE05] forceKeepHistory is ON
id0P6S✅must generate history when updating an event
idNZQB✅must generate history when trashing an event
[VERS] Versioning [VE06] Streams
idH1PK✅must generate events’ history when their stream is deleted with mergeEventsWithParents=true since their streamId is modified
id95TJ✅must delete the events’ history when their stream is deleted with mergeEventsWithParents=false and deletionMode=‘keep-nothing’
id4U91✅must keep the events’ minimal history when their stream is deleted with mergeEventsWithParents=false and deletionMode=‘keep-authors’
idD4CY✅must not delete the events’ history when their stream is deleted with mergeEventsWithParents=false and deletionMode=‘keep-everything’
[VERS] Versioning [VE07] Users
id4ETL✅must allow reusing unique values after they are in history
[WH01] webhooks [WH02] GET / [WH08] when using an app token
idR5KD✅should return a status 200 with a webhooks object which is an array
id67CX✅should fetch all webhooks reachable by an app token
idWSJG✅should not fetch any Webhook outside its scope
[WH01] webhooks [WH02] GET / [WH09] when using a personal token
id6MNC✅should return a status 200 with a webhooks object which is an array
id4YFQ✅should fetch all webhooks for the user
[WH01] webhooks [WH02] GET / [WH10] when using a shared token
idRIZV✅should return a status 200 with a webhooks object which is an array
[WH01] webhooks [WH03] GET /:webhookId [WH11] when using an app token [WH12] when fetching an existing webhook inside its scope
idXMB7✅should return a status 200 with a webhook object
[WH01] webhooks [WH03] GET /:webhookId [WH11] when using an app token [WH13] when fetching an existing webhook outside of its scope
idBDC2✅should return a status 403 with a forbidden error
[WH01] webhooks [WH03] GET /:webhookId [WH11] when using an app token [WH14] when fetching an unexistant webhook
idO6MM✅should return a status 404 with a unknown resource error
[WH01] webhooks [WH03] GET /:webhookId [WH15] when using a personal token
idD8YQ✅should return a status 200 with a webhook object
[WH01] webhooks [WH03] GET /:webhookId [WH16] when using a shared token
id604H✅should return a status 200 with a webhook object
[WH01] webhooks [WH04] POST / [WH17] when using an app token [WH18] when providing a valid webhook
idZ1XD✅should return a status 201 with the created webhook
idXKLU✅should save it to the storage
[WH01] webhooks [WH04] POST / [WH17] when using an app token [WH19] when providing an existing url
id60OQ❓should return a status 409 with a collision error error
[WH01] webhooks [WH04] POST / [WH17] when using an app token [WH20] when providing invalid parameters [WH21] when url is not a string
id3VIU✅should return a status 400 with a invalid parameters error
[WH01] webhooks [WH04] POST / [WH22] when using a shared token [WH23] when providing a valid webhook
idYTLW✅should return a status 201 with the created webhook
idUC6J✅should save it to the storage
[WH01] webhooks [WH04] POST / [WH24] when using a personal token [WH25] when providing a valid webhook
id3AZO✅should return a status 403 with a forbidden error
[WH01] webhooks [WH05] PUT /:webhookId [WH26] when using an app token [WH27] when updating an existing webhook [WH28] when changing a valid parameter
idC9FU✅should return a status 200 with the updated webhook
idJSOH✅should apply the changes to the storage
[WH01] webhooks [WH05] PUT /:webhookId [WH26] when using an app token [WH27] when updating an existing webhook [WH29] when changing a readonly parameter
idPW4I✅should return a status 403 with an invalid parameter error
[WH01] webhooks [WH05] PUT /:webhookId [WH26] when using an app token [WH30] when updating a webhook outside its scope
id8T2G✅should return a status 403 with a forbidden error
[WH01] webhooks [WH05] PUT /:webhookId [WH26] when using an app token [WH31] when updating an unexistant webhook
idAR5R✅should return a status 404 with an unknown resource error
[WH01] webhooks [WH05] PUT /:webhookId [WH32] when using a personal token [WH33] when providing valid parameters
idLCKN✅should return a status 200 with the updated webhook
[WH01] webhooks [WH05] PUT /:webhookId [WH34] when using a shared token [WH35] when providing valid parameters
idTMIZ✅should return a status 200 with the updated webhook
[WH01] webhooks [WH06] DELETE /:webhookId [WH36] when using an app token [WH37] when deleting an existing webhook
idA0CG✅should return a status 200 with the webhook deletion
idKA98✅should delete it in the storage
[WH01] webhooks [WH06] DELETE /:webhookId [WH36] when using an app token [WH38] when deleting an unexistant webhook
idZPRT✅should return a status 404 with an unknown resource error
[WH01] webhooks [WH06] DELETE /:webhookId [WH36] when using an app token [WH39] when deleting an already deleted webhook
id5UX7✅should return a status 404 with an unknown resource error
[WH01] webhooks [WH06] DELETE /:webhookId [WH36] when using an app token [WH40] when deleting a webhook outside of its scope
id7O0F✅should return a status 403 with a forbidden error
[WH01] webhooks [WH06] DELETE /:webhookId [WH41] when using a personal token [WH42] when deleting an existing webhook
idP6X4✅should return a status 200 with the webhook deletion
[WH01] webhooks [WH06] DELETE /:webhookId [WH43] when using a shared token [WH44] when deleting an existing webhook
idOZZB✅should return a status 200 with the webhook deletion
[WH01] webhooks [WH07] POST /:webhookId/test [WH45] when using an app token [WH46] when the webhook exists [WH47] when the URL is valid
idZM2B✅should return a status 200 with a webhook object
idQ7KL✅should send a POST request to the URL
[WH01] webhooks [WH07] POST /:webhookId/test [WH45] when using an app token [WH46] when the webhook exists [WH48] when the URL is invalid
idKLRO✅should return a status 400 with an error object
[WH01] webhooks [WH07] POST /:webhookId/test [WH45] when using an app token [WH49] when the webhook does not exist
idKXA8✅should return a status 404 with a unknown resource error
[WH01] webhooks [WH07] POST /:webhookId/test [WH45] when using an app token [WH50] when the webhook is outside of its scope
idKZJD✅should return a status 403 with a forbidden error
[WH01] webhooks [WH07] POST /:webhookId/test [WH51] when using a personal token [WH52] when the webhook exists
idHYZZ✅should return a status 200 with a webhook object
idSBI7✅should send a POST request to the URL
[WH01] webhooks [WH07] POST /:webhookId/test [WH53] when using a shared token [WH54] when the webhook exists
idO8PB✅should return a status 200 with a webhook object
idC62I✅should send a POST request to the URL

audit component

Summary

63tests total
63✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[ASTE] Audit Streams and Events [AS01] streams.get
idU2PV✅must retrieve access and actions substreams
idD7WV✅forbid listing of all accesses
id7SGO✅must allow listing one accesses (stream) with appAccess
idXP27✅must retrieve all available streams with a personal token
idWOIG✅appToken must not retrieve list of available actions
idTFZL✅personalToken must retrieve list of available actions
[ASTE] Audit Streams and Events [AS02] events.get
idTJ8S✅must retrieve logs by time range
id8AFA✅must retrieve logs by action
id0XRA✅personal token must retrieve all audit logs
id31FM✅appAccess must retrieve only audit logs for this access (from auth token then converted by the core)
idBLR4✅Invalid token should return an error
[AUDT] Audit [AT01] when making valid API calls
idWTNL✅must return 200
idUZEV✅must return logs when queried
[AUDT] Audit [AT01] when making valid API calls [AT02] when making a call that is not audited
idNJFO✅validates the response
[AUDT] Audit [AT01] when making valid API calls [AT03] when making a call that has its own custom accessId
id81O6✅validates the response
idG7UV✅must return logs when queried
[AUDT] Audit [AT01] when making valid API calls [AT04] when making a call that has no userId
idJU8F✅validates the response
[AUDT] Audit [AT05] when making invalid API calls [AT51] for an unknown user
idLFSW✅validates the response
[AUDT] Audit [AT05] when making invalid API calls [AT52] with errorId "invalid-request-structure"
id7SUK✅must return 400
idN5OS✅must return logs when queried
[AUDT] Audit [AT05] when making invalid API calls [AT53] with errorId "invalid-parameters-format"
idXX4D✅must return 400
idBZT8✅must return logs when queried
[AUDT] Audit [AT05] when making invalid API calls [AT54] with errorId "unknown-referenced-resource"
id9ZGI✅must return 400
idOBQ8✅must return logs when queried
[AUDT] Audit [AT05] when making invalid API calls [AT55] with errorId "invalid-access-token"
idASLZ✅must return 403
id6CZ0✅must return logs when queried
[AUDT] Audit [AT05] when making invalid API calls [AT56] with errorId "forbidden"
idWUUW✅must return 403
id14LS✅must return logs when queried
[AUDT] Audit [AT05] when making invalid API calls [AT57] with errorId "unknown-resource"
id176G✅must return 404
id7132✅must return logs when queried
[AUDT] Audit [AT05] when making invalid API calls [AT58] with a malformed request body
idDZDP✅must return 400
idZNP4✅must not record logs
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT62] when including all
idADZL✅validates logging and storage
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT63] when including all, but a few
idQ2H9✅validates logging and storage
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT64] when only including a few
idWDZ9✅validates logging and storage
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT65] when including nothing
idNP6H✅validates logging and storage
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT66] when using a method aggregate (here "events.all")
idL2KG✅validates logging and storage
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT67] when excluding a few
idJBPZ✅validates logging and storage
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT68] when including and excluding some - without intersection
id6GVQ✅validates logging and storage
[AUDT] Audit [AT06] Filtering [AT61] when filtering by calledMethods [AT69] when including and excluding some - with intersection
idUK0K✅validates logging and storage
[AINT] Audit events integrity
idXLEL✅created access has integrity
idZKVC✅created event has integrity
idWNWM✅must find event integrity key and record value in the audit log
idU09J✅must find access integrity key and record value in the audit log
[ALGR] Audit legacy route
idQXCH✅must retrieve logs by time range
id4FB8✅must retrieve logs by action
idU9HQ✅personal token must retrieve all audit logs
id6RP3✅appAccess must retrieve only audit logs for this access (from auth token then converted by the core)
idR1ZF✅Invalid token should return an error
idRQUA✅StreamId not starting with “:audit:” should return an error
[AFLT] AuditFilter [AF01] validation
id3QJJ✅must accept an existing method
idYIDZ✅must accept a valid method aggregator
id74RS✅must accept “all”
idP6WW✅must throw an error when providing a malformed filter
idGFCE✅must throw an error when providing an unexisting method
idGY6E✅must throw an error when providing an invalid aggregate method
[AFLT] AuditFilter [AF02] initialization
idH8RB✅must expand aggregate methods
[ASTO] Audit Storage [AS01] receive message and write it into its own database
idKA8B✅should have written the action in the user’s database
id9VM3✅storage.getActions returns a list of available actions
[SYSL] Syslog [SY01] receive message and write them to syslog
idF8SH✅default message
id9S6A✅templated message
id0PA7✅plugin filtered message
id1D5S✅plugin filtered message (SKIP)

business component

Summary

126tests total
126✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[WHBK] Webhook [WB01] send() [WB02] when sending to an existing endpoint [WB03] when the endpoint answers ASAP
idQ7B2✅should send it
idFICW✅should add a log to runs
id2VRK✅should add the correct status to the last run
idAOCP✅should add the correct timestamp to the last run
id2M6F✅should increment runCount
idS1CY✅should not increment failCount
id22X1✅should send the meta
[WHBK] Webhook [WB01] send() [WB02] when sending to an existing endpoint [WB04] when the endpoint answers with a long delay
idSRDL✅should send the second message after the first
[WHBK] Webhook [WB01] send() [WB05] when sending to an unexistant endpoint
id6UJH✅should add a log to runs
idVKUA✅should add the no status to the last run
id40UZ✅should add the correct timestamp to the last run
idUE17✅should increment runCount
idUJ2Y✅should increment failCount
idV5NH✅should increment currentRetries
[WHBK] Webhook [WB01] send() [WB06] when scheduling for a retry [WB07] when the notifications service is down
idE5VQ✅should save the run
idXP7G✅should increment currentRetries
id9AL1✅should schedule for a retry
idOHLY✅should send scheduled messages after an interval
id1VIT✅should reset error tracking properties
[WHBK] Webhook [WB01] send() [WB08] when throttling frequent calls
id73TG✅should only send the message once
idWPMH✅should accumulate messages
idYLWK✅should schedule for a retry after minInterval
idOZGP✅should send scheduled messages after an interval
id86OP✅should remove the timeout afterwards
[WHBK] Webhook [WB01] send() [WB09] when the webhook becomes inactive after failures
id768L✅should run 5 times
idPX10✅should update the state to inactive
idBLNP✅should update the stored version
idODNM✅should not run anymore
[WHBK] Webhook [WB01] send() [WB10] when the runs array gets shifted
idFYOR✅should rotate the runs
[MCTX] MethodContext [MC01] #parseAuth
idZRW8✅should parse token out
idAUIY✅should also parse the callerId when available
[MCTX] MethodContext [MC02] #retrieveAccessFromId
idOJW2✅checks expiry of the access
[MFAF] mfa/createMFAService factory
idMF1A✅returns null when mode is disabled
idMF1B✅returns null when config is missing
idMF2A✅returns a ChallengeVerifyService for mode=challenge-verify
idMF2B✅returns a SingleService for mode=single
idMF3A✅throws on unknown mode
[MFAG] mfa/generateCode
idMFG1✅returns a code of the requested length when smaller than the random source
idMFG2✅pads with leading zeroes when the random source is too short
[MFAP] mfa/Profile
idMP1A✅is inactive when content is empty
idMP1B✅is active when content has any key
idMP2A✅generateRecoveryCodes() produces 10 unique UUID strings
[MFAS] mfa/Service [MFAR] replaceAll
idMS1A✅replaces every {{ key }} occurrence in a string
idMS1B✅returns non-strings unchanged
[MFAS] mfa/Service [MFAC] replaceRecursively
idMS2A✅walks an object tree replacing string leaves
idMS2B✅does not mutate the input
idMS2C✅passes null/undefined through
[MFAS] mfa/Service [MFAB] base class
idMS3A✅challenge() and verify() throw on the abstract base
[MFAT] mfa/SessionStore
idMT1A✅create() returns a UUID v4 mfaToken and stores the session
idMT1B✅each create() yields a fresh token
idMT2A✅get() returns undefined for unknown ids
idMT2B✅clear() removes the session and returns true
idMT2C✅clear() is idempotent — second clear returns false
idMT3A✅sessions auto-expire after the ttl
idMT4A✅clearAll() drops every session and cancels every timer
[BRQS] BatchRequest [BR01] .parse
idQJ6L✅should parse the happy case
idVV2O✅accepts an empty batch
id0NWO✅throws if format is missing or wrong
id881Y✅throws if another type is passed in
id2PZ0✅throws if envelope doesn’t have a data attribute
[BREL] BatchRequestElement [BE01] .parse(obj)
idAGQK✅should parse a good looking object
idLWME✅fails if input is not an Object
idBU7Q✅fails if eventId is missing or the wrong type
[DMTX] DataMatrix [DM01] .parse(obj)
id576J✅should accept the happy path
idIQTE✅refuses if not an object
idWQGB✅refuses if format is not flatJSON
id34RS✅refuses if fields are not strings
idM5BI✅refuses if points is not an array
idV0SH✅refuses if field names are not correct
idSBU1✅refuses if data cannot be coerced
[DMTX] DataMatrix [DM02] #eachRow
idQUQ3✅should iterate over all matrix rows
[DMTX] DataMatrix [DM03] #transform
idL03R✅should call fn for each cell
id7BRV✅should store the return value in the matrix
[DMTX] DataMatrix [DM04] #minmax()
idQGY6✅returns the minimum and maximum deltaTime used
idROK8✅throws an error if the matrix is empty
id79DA✅throws an error if the deltaTime is missing
[SROW] business.series.Row [SR01] toStruct
idNJ4G✅should return a js object for the row
[SREP] business.series.Repository [SR01] with stubbed out connection
id0UEA✅should produce series objects for events
[TYPR] business.types.TypeRepository [TY01] type list update
idWMDW✅should work (must be called manually)
id6VL6✅should fail gracefully
[TYPR] business.types.TypeRepository [TY02] basic types like mass/kg
idEEWV✅should be known
idJ0CJ✅should return a type instance allowing conversion
id8WI1✅should throw when conversion fails
idWKCS✅should coerce to number during validation
[TYPR] business.types.TypeRepository [TY03] boolean type boolean/bool
idE2Y1✅should be known
id8FHU✅should return a type instance allowing conversion
id8U3U✅should coerce to boolean during validation
[TYPR] business.types.TypeRepository [TY04] complex types like position/wgs84
id05LA✅should be known
id0QZ3✅should return a complex type instance
[TYPR] business.types.TypeRepository [TY05] complex types on several levels like message/facebook
idD0GT✅should return the correct value type for all fields
id3BC9✅should return the correct value type for optional fields
idIVPF✅should resolve nested fields
id5PMM✅does NOT handle requiredFields fully yet: only surface requirements are returned
[TYPR] business.types.TypeRepository [TY06] placeholder types like picture/attached
id78HI✅should be known
id85BQ✅should return a type instance allowing conversion
[TYPR] business.types.TypeRepository [TY07] series types like series:mass/kg
idSQNQ✅should be known
idIR3B✅should inform about fields correctly
[TYPR] business.types.TypeRepository [TY08] validate()
idVK9J✅should accept an array as a known type’s event content
[TYPV] business.types.TypeValidator
idAE3Q✅should be produced via a type repository
idJT1F✅should validate simple types
idQIVH✅should validate complex types
[USRP] Users repository [UR01] createUser()
id7C22✅must throw an item already exists error when username field is not unique
id6CFE✅must throw an item already exists error when email field is not unique

cache component

Summary

10tests total
10✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[CACH] Cache
idFELT✅Second get stream must be faster that first one
idXDP6✅Cache should reset permissions on stream structure change when moving a stream in and out
[SYNC] Synchro
idLHGV✅Should register listener on userId when using setStreams
idRYQD✅Should register listener on userId when using setAccessLogic.
idR7I6✅Should unset access Logic on unset Message
id8M1B✅Registered listener should be removed on clearEvent
idKF7E✅Registered listener should be removed on unsetUser
idOKHQ✅Listeners should not receive “internal” messages
idY5GA✅Listeners should receive transport messages UNSET_USER_DATA
idY5GU✅Listeners should receive transport messages UNSET_USER

dns-server component

Summary

26tests total
26✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[DNS] DNS Server Root domain (dns.Resolver)
idDN01✅must resolve A record for root domain
idDN02✅must resolve AAAA record for root domain
idDN03✅must resolve MX records for root domain
idDN04✅must resolve NS records for root domain
idDN05✅must resolve TXT records for root domain
[DNS] DNS Server Root domain (raw UDP)
idDN06✅must return SOA record for root domain
idDN07✅must resolve CAA record for root domain
[DNS] DNS Server Static subdomains
idDN10✅must resolve CNAME for www subdomain
idDN11✅must resolve CNAME for reg subdomain
idDN12✅must resolve A record for static A subdomain
[DNS] DNS Server Username resolution
idDN20✅must resolve username to core IP (A record)
idDN21✅must resolve username to different core IP
idDN22✅must resolve username via CNAME when core has no IP
idDN23✅must return NXDOMAIN for unknown username
idDN24✅must resolve username AAAA when core has IPv6
[DNS] DNS Server Cluster discovery (lsc)
idDN30✅must return all core IPs for lsc.{domain}
[DNS] DNS Server updateStaticEntry
idDN40✅must update runtime entry for ACME challenge
idDN41✅must reject updates that would shadow a config-static entry
[DNS] DNS Server Non-matching domain
idDN50✅must return NXDOMAIN for queries outside our domain
[DNP] DNS Server — PlatformDB persistence
idDNP01✅must load persisted records from PlatformDB on start()
idDNP02✅updateStaticEntry must persist to PlatformDB
idDNP03✅persisted records must survive a “restart”
idDNP04✅config-static entries MUST shadow PlatformDB records
idDNP05✅updateStaticEntry for a config-key must throw and leave PlatformDB untouched
idDNP06✅periodic refresh must pick up records added after start() (multi-core propagation)
idDNP07✅deleteStaticEntry must remove from PlatformDB and memory

externals component

Summary

1tests total
0✅ passing
1❓ pending
0❌ failing

Tests

IdStatusTest

hfs-server component

Summary

60tests total
60✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[HFBT] Storing BATCH data in a HF series [HB01] Use Case: Store data in InfluxDB, Verification on either half
idQ2IS✅should store data correctly
[HFBT] Storing BATCH data in a HF series [HB02] POST /:user_name/series/batch
idA3BQ✅should return core-metadata in every call
idQHM5✅should fail without ‘Authorization’ header
[HFBT] Storing BATCH data in a HF series [HB02] POST /:user_name/series/batch [HB03] when the token has no permissions on the event
idR57L✅fails
[HFBT] Storing BATCH data in a HF series [HB02] POST /:user_name/series/batch [HB04] when the token has a "create-only" permission
idATAH✅should work
[HFBT] Storing BATCH data in a HF series [HB02] POST /:user_name/series/batch [HB05] when using a metadata updater stub
idOO01✅should schedule a metadata update on every store
[HFSQ] Querying data from a HF series
idQ1X1✅should should accept a query with authentication token header
idQ1X2✅should accept a query with authentication token in url parameter
idQ1X3✅must accept basic auth schema
idRAIJ✅should return core-metadata in every call
idXAI2✅should accept a query when the authorized permission is on the event’s 2nd streamId
idI2ZH✅should refuse a query for an unknown user
idEYCA✅should refuse a query missing the authorization token
idOINY✅should refuse a query containing an unauthorized token
idQ991✅should return an unknown resource error when querying data for an nonexistent event id
idQMC7✅should refuse a query containing parameters with the wrong format
idHGVV✅should refuse a query when toTime is before fromTime
idXI4M✅should refuse a query with a “create-only” token
[SDHF] Storing data in a HF series [SD01] Use Case: Store data in InfluxDB, Verification on either half
idZUBI✅should convert timestamp to deltaTime
idGZIZ✅should store data correctly
idKC15✅should return data once stored
idYALY✅should accept a request when the authorized permission is on the event’s 2nd streamId
[SDHF] Storing data in a HF series [SD02] UPDATE and DELETE on handling event affect the serie
idUD1C✅moving event in time does empty the cache
idUD2C✅trashed event cannot be written to
idZTG6✅deleted events deletes series
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD31] bypassing authentication [SD32] with auth success
idN3PM✅stores data into InfluxDB
idTL0D✅should return core-metadata in every call
idRESC✅should reject non-JSON bodies
idKT1R✅responds with headers that allow CORS on OPTIONS
idH1CG✅responds with headers that allow CORS on POST
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD31] bypassing authentication [SD32] with auth success [SD33] when request is malformed
id96HC✅should be rejected (format is not flatJSON)
id38W3✅should be rejected (matrix is not square - not enough fields)
idGJL5✅should be rejected (no negative deltaTime)
idGJL4✅should be rejected (value types are not all valid)
idJJRO✅should be rejected (missing deltaTime column)
idLKFG✅should be rejected (missing value column for a simple input)
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD31] bypassing authentication [SD32] with auth success [SD34] when using a metadata updater stub
idGU3L✅should schedule a metadata update on every store
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD31] bypassing authentication [SD35] with auth failure
idNLAW✅refuses invalid/unauthorized accesses
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD36] storing data in different formats
idY3BL✅stores data of any basic type
id3WGH✅stores data of complex types
id1NDB✅doesn’t accept data in non-series format
idYMHK✅stores strings
idZL7C✅stores floats
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD37] complex types such as ratio/generic
idDTZ2✅refuses to store when deltaTime is present twice (ambiguous!)
idUU4R✅refuses to store when other fields are present twice (ambiguous!)
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD37] complex types such as ratio/generic [SD38] null fields
id7UZT✅accept null fields
id7UTT✅do not accept null for required fields
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD37] complex types such as ratio/generic [SD39] when not all required fields are given
idFNDT✅refuses to store when not all required fields are given
idH525✅returns error id “invalid-request-structure”
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD37] complex types such as ratio/generic [SD40] when field names don't match the type
idAJMS✅refuses to store when field names don’t match the type
id7CR7✅returns the error message with the id “invalid-request-structure”
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD41] complex types such as position/wgs84
idUDHO✅allows storing any number of optional fields, on each request
idJDTH✅refuses unknown fields
[SDHF] Storing data in a HF series [SD03] POST /events/EVENT_ID/series [SD42] using a "create-only" permissions
idYCGZ✅should work
[METL] Metadata Loader
idU6F2✅should allow write access to series
[METC] Metadata Cache
idO8AE✅returns loaded metadata for N minutes
[HFSV] Server
idO84I✅can be constructed
[HFSV] Server [HS01] .start
id1VEL✅starts a http server on configured port
[HFCT] Controller [HC01] storeSeriesData
id3BYC✅should reject queries if the authorization header is missing
idU0WB✅should reject queries if the eventId is missing

mall component

Summary

22tests total
22✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[KVDB] Per-store key-value DB
id2Z7L✅Must set and get key-value data
[MSTE] Stores Streams & Events [MS01] Streams [MS02] GET
id1Q12✅Must retrieve dummy streams when querying parentId
idUVQ2✅Must retrieve “yo” streams and “:dummy:” when requesting “*”
idXC20✅master token must retrieve “yo” streams and all stores when requesting “*”
idXC21✅personal token must retrive :dummy: stream structure
idXC22✅app token must retrive :dummy: stream structure
idXC23✅master token must retrive :dummy: stream structure
id3ZTM✅Root streams must have null parentIds “*”
[MSTE] Stores Streams & Events [MS01] Streams [MS03] CREATE
id2Q12✅Create a stream under dummy
id2Q13✅Should fail creating outside of store
id2Q14✅Should fail creating outside of store 2
[MSTE] Stores Streams & Events [MS01] Streams [MS04] UPDATE
id3Q12✅Create a stream under dummy
id3Q13✅Should fail moving a stream outside of store
[MSTE] Stores Streams & Events [MS05] Events [MS06] GET
idXD21✅personal token must retrive :dummy: events
idXD22✅master token must retrive :dummy: events
idXD23✅app token must retrive :dummy: events
[MSTE] Stores Streams & Events [MS05] Events [MS07] CREATE
idYD21✅create event on :dummy:
idYD22✅create with a given id on :dummy:
idYD23✅should fail on mismatching stream and id in store
idYD24✅should fail on mismatching stream in store and id
[MSTE] Stores Streams & Events [MS05] Events [MS08] UPDATE
idZD21✅update event :dummy:dummyevent0
idZD22✅should fail moving an event to another store

messages component

Summary

7tests total
7✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[PRMV] Pubsub removers
idLVNK✅remover works
[NPUB] TcpPublisher
idS386✅should construct
idI21M✅delivers messages to “USERNAME”
[NSUB] TcpSubscriber
idDMMP✅should construct
[NSUB] TcpSubscriber [NS01] when subscribed to "foobar" [NS02] subscribe("USERNAME")
id4MAI✅accepts messages from USERNAME.sok1 and dispatches them to sinks
id47BP✅ignores messages from other users
[NSUB] TcpSubscriber [NS01] when subscribed to "foobar" [NS03] unsubscribe()
idL49E✅should unsubscribe from TCP broker

middleware component

Summary

8tests total
8✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[LA01] loadAccess middleware [LA02] when an access is actually loaded in request context
idOD3D✅should add the access id as Pryv-access-id header if token is valid
idUDW7✅should still set the Pryv-access-id header in case of error (e.g. expired token)
[LA01] loadAccess middleware [LA03] when the access can not be loaded (e.g. invalid token)
id9E2D✅should not set the Pryv-access-id header
[APIV] APIVersion#version [AV01] when a ".api-version" file exists in the project and is !== that 1.2.3
id5ICP✅reads .api-version and returns that constant
[APIV] APIVersion#version [AV02] when a ".api-version" file exists in the project and is 1.2.3 (sentinel)
idHV40✅should return git tag version
[SDTP] subdomainToPath middleware [SD01] using a minimal application
idV0R9✅should not transform illegal usernames
idQ5A5✅should transform username into a path segment
idIDDE✅should accept dashes

platform component

Summary

0tests total
0✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest

previews-server component

Summary

15tests total
15✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[EP01] event previews [EP02] GET //preview
idNRT9✅must return JPEG previews for “picture/attached” events and cache the result
idFEWU✅must accept “.jpg” extension in the path (backwards-compatibility)
idPBC1✅must adjust the desired size to the bigger standard size (if exists)
id415L✅must limit the desired size to the biggest standard size if too big
idCWTQ✅must serve the cached file if available
id2MME✅must regenerate the cached file if obsolete
id7Y91✅must respond with “no content” if the event type is not supported
id61N8✅must return a proper error if the event does not exist
idVIJO✅must forbid requests missing an access token
idFAK4✅must forbid requests with unauthorized accesses
idQUM3✅must return a proper error if event data is corrupted (no attachment object)
idGSDF✅must work with animated GIFs too
[EP01] event previews [EP03] POST /clean-up-cache
idFUYE✅must clean up cached previews not accessed for one week by default
idG5JR✅must ignore files with no readable extended attribute
[PIDX] (index) [PI01] OPTIONS /
idE5MW✅should return OK

storage component

Summary

13tests total
13✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[UAST] Users Account Storage UserAccountStorage conformance addPasswordHash()
idB2I7✅must throw an error if two passwords are added with the same time
[UAST] Users Account Storage UserAccountStorage conformance getCurrentPasswordTime()
id85PW✅must return the time of the current password
idV54S✅must throw an error if there is no password for the user id
[UAST] Users Account Storage UserAccountStorage conformance passwordExistsInHistory()
id1OQP✅must return true when looking for existing passwords
idDO33✅must return false when looking for a non-existing password
idFEYP✅must return false when looking for an existing password that is beyond the given range

utils component

Summary

10tests total
10✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[TRUT] tree utils [TU01] buildTree()
id32CB✅must build a correct tree for a given consistent array
idVVVS✅must throw an error if objects do not contain the necessary properties
idCEUF✅must throw an error if the object in argument is not an array
[TRUT] tree utils [TU02] flattenTree()
id11JJ✅must build a correct array for a given tree
idOVJM✅must throw an error if the object in argument is not an array
[TRUT] tree utils [TU03] findInTree()
idS1N0✅must return the first item matching the given iterator function
idSI6L✅must return null if no item matches the given iterator function
[TRUT] tree utils [TU04] filterTree()
idYIE6✅must return only items matching the given iterator function
[TRUT] tree utils [TU05] collect()
idAU44✅must return an array with values matching the iterator function for each item in the tree
[TRUT] tree utils [TU06] expandIds()
idPFJP✅must return an array with the ids passed in argument plus those of all their descendants

webhooks component

Summary

8tests total
8✅ passing
0❓ pending
0❌ failing

Tests

IdStatusTest
[WH01] webhooks [WH02] when loading Webhooks on startup [WH03] when booting the webhooks application
idYD6N✅should send a boot message to all active webhooks
idUM4T✅should send nothing to inactive webhooks
[WH01] webhooks [WH02] when loading Webhooks on startup [WH04] when creating an event in a Webhook scope [WH05] when the notifications server is running
id3TMH✅should send API call to the notifications server
id7N4L✅should update the Webhook’s data to the storage
[WH01] webhooks [BBB] when creating a Webhook through api-server [WH06] when the notifications server is running returning 400
idEXQD✅should register a new webhook in the service through pubsub
id8Q4E✅should deactivate after failures
idPY61✅should be run again when updating its state
[WH01] webhooks [WH07] when there are running webhooks [WH08] when deleting a webhook through API server
id904D✅should deactivate the current running webhook through pubsub