| [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 |