diff --git a/swh/web/tests/browse/views/data/directory_test_data.py b/swh/web/tests/browse/views/data/directory_test_data.py index eed39c3a..51be3647 100644 --- a/swh/web/tests/browse/views/data/directory_test_data.py +++ b/swh/web/tests/browse/views/data/directory_test_data.py @@ -1,478 +1,8 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information # flake8: noqa -stub_root_directory_sha1 = '08e8329257dad3a3ef7adea48aa6e576cd82de5b' - -stub_root_directory_data = \ -[ - { - "checksums": { - "sha1": "97d7a922a89fdcf4399e8c51555b7f624575310e", - "sha1_git": "7752290577d11e12c8402fa03ee9344d9ed02f8f", - "sha256": "ad98bd676fc2902b8d9ece3c3298d9ec481bd2749aae11ad6d00e8899a6e0c72" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 76, - "name": ".arcconfig", - "perms": 33188, - "status": "visible", - "target": "7752290577d11e12c8402fa03ee9344d9ed02f8f", - "target_url": "/api/1/content/sha1_git:7752290577d11e12c8402fa03ee9344d9ed02f8f/", - "type": "file" - }, - { - "checksums": { - "sha1": "745f095b107b91d97dc789d07a2a0b8faaa8700f", - "sha1_git": "8a79cd50ff302720c5543f5cfa9cccad2489f3b8", - "sha256": "279419b197312d2be9fd30f5af3590cfc81d68ddd5ccfccb2f1279fdc355c081" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 155, - "name": ".gitignore", - "perms": 33188, - "status": "visible", - "target": "8a79cd50ff302720c5543f5cfa9cccad2489f3b8", - "target_url": "/api/1/content/sha1_git:8a79cd50ff302720c5543f5cfa9cccad2489f3b8/", - "type": "file" - }, - { - "checksums": { - "sha1": "ba15a7a0a3f0742e53966599e65ed8e8935e1139", - "sha1_git": "6365ea05fcd19c6642cb7332ad3e6a0963ae6b0b", - "sha256": "8fc39a39f3950f3a8a98fcb60b9a0b06b0c6df3ee74899cb206b2d50050ebd73" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 59, - "name": ".kateconfig", - "perms": 33188, - "status": "visible", - "target": "6365ea05fcd19c6642cb7332ad3e6a0963ae6b0b", - "target_url": "/api/1/content/sha1_git:6365ea05fcd19c6642cb7332ad3e6a0963ae6b0b/", - "type": "file" - }, - { - "checksums": { - "sha1": "ca3eb23cc16b3512763ac286727dd72d78035ecf", - "sha1_git": "5449a540cb927a2cf95072e74c8f53e67dcb061e", - "sha256": "6345d2855ead4ed3f4724408f19d63fb1b7e3492a975568920370dae54d66816" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 241, - "name": ".kateproject", - "perms": 33188, - "status": "visible", - "target": "5449a540cb927a2cf95072e74c8f53e67dcb061e", - "target_url": "/api/1/content/sha1_git:5449a540cb927a2cf95072e74c8f53e67dcb061e/", - "type": "file" - }, - { - "checksums": { - "sha1": "ed57cfa75fa0ca475b00920d5338bb4ff51c7114", - "sha1_git": "91c957be760b9c961ccae698fb0e041ef310365c", - "sha256": "df82603f10480d80001e38ae98eb8918a8b9c2cb19e5fb5370ca1d94eff9fb41" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 135, - "name": ".reviewboardrc", - "perms": 33188, - "status": "visible", - "target": "91c957be760b9c961ccae698fb0e041ef310365c", - "target_url": "/api/1/content/sha1_git:91c957be760b9c961ccae698fb0e041ef310365c/", - "type": "file" - }, - { - "checksums": { - "sha1": "599e37adf3169c74333ba2378acc23c42270918c", - "sha1_git": "b3b1c238d6ae998d85d3193df1c3c30b722a6d87", - "sha256": "e61b10f1c0685295f5921e86014025ad59a0cad2db972f3300ec141923b56668" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 1482, - "name": "AUTHORS", - "perms": 33188, - "status": "visible", - "target": "b3b1c238d6ae998d85d3193df1c3c30b722a6d87", - "target_url": "/api/1/content/sha1_git:b3b1c238d6ae998d85d3193df1c3c30b722a6d87/", - "type": "file" - }, - { - "checksums": { - "sha1": "717cb04728a3c8e3e509368dff6f3898b170af15", - "sha1_git": "3ab996412d61e2e66e6d7ba31d0738cb7fcd6624", - "sha256": "727b93f0a54113559d6984d3a53cc96eb5bb6b9f900422a65d38907dc00798e1" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 2514, - "name": "CMakeLists.txt", - "perms": 33188, - "status": "visible", - "target": "3ab996412d61e2e66e6d7ba31d0738cb7fcd6624", - "target_url": "/api/1/content/sha1_git:3ab996412d61e2e66e6d7ba31d0738cb7fcd6624/", - "type": "file" - }, - { - "checksums": { - "sha1": "8624bcdae55baeef00cd11d5dfcfa60f68710a02", - "sha1_git": "94a9ed024d3859793618152ea559a168bbcbb5e2", - "sha256": "8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 35147, - "name": "COPYING-GPL3", - "perms": 33188, - "status": "visible", - "target": "94a9ed024d3859793618152ea559a168bbcbb5e2", - "target_url": "/api/1/content/sha1_git:94a9ed024d3859793618152ea559a168bbcbb5e2/", - "type": "file" - }, - { - "checksums": { - "sha1": "f45ee1c765646813b442ca58de72e20a64a7ddba", - "sha1_git": "65c5ca88a67c30becee01c5a8816d964b03862f9", - "sha256": "da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 7651, - "name": "COPYING-LGPL3", - "perms": 33188, - "status": "visible", - "target": "65c5ca88a67c30becee01c5a8816d964b03862f9", - "target_url": "/api/1/content/sha1_git:65c5ca88a67c30becee01c5a8816d964b03862f9/", - "type": "file" - }, - { - "checksums": { - "sha1": "e2b9735e3fe7740e377cd085eee521c819a4e736", - "sha1_git": "a96b5730ddd200d0ebec9fae6594a2eca9a1e87e", - "sha256": "c3b824a53fbc4f9a3c7e9046149383b2a39308e430c38ea8d599ed9a3fd5694f" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 25319, - "name": "COPYING.LIB", - "perms": 33188, - "status": "visible", - "target": "a96b5730ddd200d0ebec9fae6594a2eca9a1e87e", - "target_url": "/api/1/content/sha1_git:a96b5730ddd200d0ebec9fae6594a2eca9a1e87e/", - "type": "file" - }, - { - "checksums": { - "sha1": "3bb25f251eea54667d43e538365a31acf5d87cce", - "sha1_git": "acd13325a148ad05fa574b458595edb849af6b19", - "sha256": "cbde670dc8f623d61ab28a8b302648cccae22bafc616300cba0fd99c1dae7a94" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 459, - "name": "README.md", - "perms": 33188, - "status": "visible", - "target": "acd13325a148ad05fa574b458595edb849af6b19", - "target_url": "/api/1/content/sha1_git:acd13325a148ad05fa574b458595edb849af6b19/", - "type": "file" - }, - { - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 0, - "name": "addons", - "perms": 16384, - "target": "8cd85958b0c15fbf7537219685d3d79185a5d503", - "target_url": "/api/1/directory/8cd85958b0c15fbf7537219685d3d79185a5d503/", - "type": "dir" - }, - { - "checksums": { - "sha1": "bdd4876c9d8150f19e520e1517dec705c494b78b", - "sha1_git": "9220caf4063726dc63ceda42a373b2be38a3046d", - "sha256": "78d4776f681c6c246227dcdb002fde2ab2c962ac1f0c70feac37ad2fe6947be7" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 222, - "name": "config.h.cmake", - "perms": 33188, - "status": "visible", - "target": "9220caf4063726dc63ceda42a373b2be38a3046d", - "target_url": "/api/1/content/sha1_git:9220caf4063726dc63ceda42a373b2be38a3046d/", - "type": "file" - }, - { - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 0, - "name": "doc", - "perms": 16384, - "target": "4b1bf7180b4c07a103efbcc3e205472ee1ea353b", - "target_url": "/api/1/directory/4b1bf7180b4c07a103efbcc3e205472ee1ea353b/", - "type": "dir" - }, - { - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 0, - "name": "kate", - "perms": 16384, - "target": "74e9390431545b89360f75bab447b55fd96137de", - "target_url": "/api/1/directory/74e9390431545b89360f75bab447b55fd96137de/", - "type": "dir" - }, - { - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 0, - "name": "kwrite", - "perms": 16384, - "target": "2eb07a97076322bfc1f9408007409f43cbbd4d8c", - "target_url": "/api/1/directory/2eb07a97076322bfc1f9408007409f43cbbd4d8c/", - "type": "dir" - }, - { - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 0, - "name": "mac", - "perms": 16384, - "target": "4c3f56a45f23c6cc96d7771b511bc5e3886ec649", - "target_url": "/api/1/directory/4c3f56a45f23c6cc96d7771b511bc5e3886ec649/", - "type": "dir" - }, - { - "checksums": { - "sha1": "196915f25d1fcde542515e036fbbdadf47047681", - "sha1_git": "e7195945633a20ff5e64d2556ffc4872a0c4b4dd", - "sha256": "e621462626a86762318d7ad2df0460afb79285c25a78aae1db2a880014e814a5" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 394, - "name": "run-tests-in-xvfb.sh", - "perms": 33261, - "status": "visible", - "target": "e7195945633a20ff5e64d2556ffc4872a0c4b4dd", - "target_url": "/api/1/content/sha1_git:e7195945633a20ff5e64d2556ffc4872a0c4b4dd/", - "type": "file" - }, - { - "checksums": { - "sha1": "953d9f0a118652eedb1c46fe95da4f14de54605f", - "sha1_git": "31369dac85e95fdd9439feb6b3fa372efaf48889", - "sha256": "6f3a19457ffbdd6b2d37d7fab6525e7a18f9f315d7ad53b1c050712211d9fd92" - }, - "dir_id": "08e8329257dad3a3ef7adea48aa6e576cd82de5b", - "length": 3644, - "name": "urlinfo.h", - "perms": 33188, - "status": "visible", - "target": "31369dac85e95fdd9439feb6b3fa372efaf48889", - "target_url": "/api/1/content/sha1_git:31369dac85e95fdd9439feb6b3fa372efaf48889/", - "type": "file" - } -] - -stub_sub_directory_data = \ -[ - { - "checksums": { - "sha1": "4f322c36a42a51a4ac51cb31059a5e9b62c0b8d6", - "sha1_git": "aa5a37e6a918d30bf0032c6cfba79f1572c293b0", - "sha256": "d3abb3c551e024c420db4f9a309b26b87954c5c73ad903052d079a009e9d7f04" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 3575, - "name": "katesession.cpp", - "perms": 33188, - "status": "visible", - "target": "aa5a37e6a918d30bf0032c6cfba79f1572c293b0", - "target_url": "/api/1/content/sha1_git:aa5a37e6a918d30bf0032c6cfba79f1572c293b0/", - "type": "file" - }, - { - "checksums": { - "sha1": "c42547257b0a422f1258074eb453c03269bf353e", - "sha1_git": "cd40bc3e3e61804eca48be777464e194839bc367", - "sha256": "8e460223b074466d121e6d0b3869a8c56d8bf8dd648a7076f8b9707efb3e922f" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 3884, - "name": "katesession.h", - "perms": 33188, - "status": "visible", - "target": "cd40bc3e3e61804eca48be777464e194839bc367", - "target_url": "/api/1/content/sha1_git:cd40bc3e3e61804eca48be777464e194839bc367/", - "type": "file" - }, - { - "checksums": { - "sha1": "613e819800af57639942bf18c110b0dbec9cfefe", - "sha1_git": "8e4e46f7d012362488608eb3029f0246d3275d5e", - "sha256": "4f9f6f4fd71b135c03b22d8dd0fec7e7feca2b9257ffc46f55f243a5bf1a707d" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 6473, - "name": "katesessionchooser.cpp", - "perms": 33188, - "status": "visible", - "target": "8e4e46f7d012362488608eb3029f0246d3275d5e", - "target_url": "/api/1/content/sha1_git:8e4e46f7d012362488608eb3029f0246d3275d5e/", - "type": "file" - }, - { - "checksums": { - "sha1": "658cb1cce9ae3ea178194763cbfa8213c11bc6c1", - "sha1_git": "c2d1ee22754bd11be7e50668f09571171f449293", - "sha256": "0e65bf00d7e72c9b4131408c0f54f45db4a8945533d52cdb859b617d2c24a2d5" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 1838, - "name": "katesessionchooser.h", - "perms": 33188, - "status": "visible", - "target": "c2d1ee22754bd11be7e50668f09571171f449293", - "target_url": "/api/1/content/sha1_git:c2d1ee22754bd11be7e50668f09571171f449293/", - "type": "file" - }, - { - "checksums": { - "sha1": "d2e6159840c9f3aa7774582beb93c6c8de7f6011", - "sha1_git": "5b7ecf823a688a1dc391f2989b556f258b53c92c", - "sha256": "aed0fa5d3d41db5fa4f20a4f3c8cae9cb0ce4b0cbd0a661b931ec457004302fe" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 1370, - "name": "katesessionchooseritem.h", - "perms": 33188, - "status": "visible", - "target": "5b7ecf823a688a1dc391f2989b556f258b53c92c", - "target_url": "/api/1/content/sha1_git:5b7ecf823a688a1dc391f2989b556f258b53c92c/", - "type": "file" - }, - { - "checksums": { - "sha1": "2796ed193e91afb5e647934873c3ca2e5f9fd089", - "sha1_git": "a1191a6c9a2170631948c642352629d64d654727", - "sha256": "c18956963dfc6ac66e6de05449020077791fee681056797581edc1b20df37be3" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 5861, - "name": "katesessionmanagedialog.cpp", - "perms": 33188, - "status": "visible", - "target": "a1191a6c9a2170631948c642352629d64d654727", - "target_url": "/api/1/content/sha1_git:a1191a6c9a2170631948c642352629d64d654727/", - "type": "file" - }, - { - "checksums": { - "sha1": "4fdc1150cd65ac7502166cb958c5c8422976bd4b", - "sha1_git": "feb31d7bacc40b5d67f858917dfdb05ef9e01aee", - "sha256": "19a7cabf17923fa91d048a2928c4b8b5f04ca6a46c7ce93bfa711c56c8f203d7" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 1838, - "name": "katesessionmanagedialog.h", - "perms": 33188, - "status": "visible", - "target": "feb31d7bacc40b5d67f858917dfdb05ef9e01aee", - "target_url": "/api/1/content/sha1_git:feb31d7bacc40b5d67f858917dfdb05ef9e01aee/", - "type": "file" - }, - { - "checksums": { - "sha1": "0e25c6ed7ba157eced5ad16888ff17267077d172", - "sha1_git": "bf3a0b1365de02563fe05ae5f75fc1fb1fbf1d78", - "sha256": "4e4a3f290c042c3cf4fc422666cf3cc97241265c78d96e3af5aecdd27af3962c" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 15676, - "name": "katesessionmanager.cpp", - "perms": 33188, - "status": "visible", - "target": "bf3a0b1365de02563fe05ae5f75fc1fb1fbf1d78", - "target_url": "/api/1/content/sha1_git:bf3a0b1365de02563fe05ae5f75fc1fb1fbf1d78/", - "type": "file" - }, - { - "checksums": { - "sha1": "096e52434e8634c827455853f8a9f35ec0c53da3", - "sha1_git": "15a710ebcb65e6399cff38194b19f568cdaf4747", - "sha256": "c0d4dda2ec68aa5b3df966b91a90fb1afedbecf67247cd710b46ede36d8bf36d" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 5622, - "name": "katesessionmanager.h", - "perms": 33188, - "status": "visible", - "target": "15a710ebcb65e6399cff38194b19f568cdaf4747", - "target_url": "/api/1/content/sha1_git:15a710ebcb65e6399cff38194b19f568cdaf4747/", - "type": "file" - }, - { - "checksums": { - "sha1": "b7e7f82f27976acf6c04649cbcc703fe8df88ba8", - "sha1_git": "2b43aebeca1dd705fcd3d185c026bbcd13863aab", - "sha256": "bd69ae83132692819edef6925cb75381b0f787f7916fb477a234d6c2968935d7" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 3821, - "name": "katesessionopendialog.cpp", - "perms": 33188, - "status": "visible", - "target": "2b43aebeca1dd705fcd3d185c026bbcd13863aab", - "target_url": "/api/1/content/sha1_git:2b43aebeca1dd705fcd3d185c026bbcd13863aab/", - "type": "file" - }, - { - "checksums": { - "sha1": "d20adf1d91c02145dadfc57929ce97382e20f8e5", - "sha1_git": "2377175320886a8de88b7e1ceeb9fd8d4d754274", - "sha256": "666f984226c47b7a2f29b379bf1bebcdd0c881ab8a7c2ef768095fa494763291" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 1599, - "name": "katesessionopendialog.h", - "perms": 33188, - "status": "visible", - "target": "2377175320886a8de88b7e1ceeb9fd8d4d754274", - "target_url": "/api/1/content/sha1_git:2377175320886a8de88b7e1ceeb9fd8d4d754274/", - "type": "file" - }, - { - "checksums": { - "sha1": "5609e7a3e71fc685cc78ee472af6313ed9339a89", - "sha1_git": "39253130c5715245cc1c6ce5ecba7a4aec9cbc4c", - "sha256": "372de75c3c0408837c1190714c64c38942b99d3339abe6446651cbf93e7ba486" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 2909, - "name": "katesessionsaction.cpp", - "perms": 33188, - "status": "visible", - "target": "39253130c5715245cc1c6ce5ecba7a4aec9cbc4c", - "target_url": "/api/1/content/sha1_git:39253130c5715245cc1c6ce5ecba7a4aec9cbc4c/", - "type": "file" - }, - { - "checksums": { - "sha1": "3b17084f875f847fd85432045b1f39536d55db39", - "sha1_git": "0fd4ea4c765e454ae0cf064192bd7cec7c106cfd", - "sha256": "853deef6938382aef789c36cac4390a59d8eafd65d11fd5ece3ecdaac25515a4" - }, - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": 1522, - "name": "katesessionsaction.h", - "perms": 33188, - "status": "visible", - "target": "0fd4ea4c765e454ae0cf064192bd7cec7c106cfd", - "target_url": "/api/1/content/sha1_git:0fd4ea4c765e454ae0cf064192bd7cec7c106cfd/", - "type": "file" - }, - { - "dir_id": "6cdf1fba5e9559e18242f7aa3fc10e1898c82f32", - "length": None, - "name": "revision", - "perms": 57344, - "target": "8750d5607ac066349d60451db1ef211a9cd97515", - "target_url": "/api/1/revision/8750d5607ac066349d60451db1ef211a9cd97515/", - "type": "rev" - } -] - - -stub_sub_directory_path = 'kate/session' +stub_root_directory_sha1 = '08e8329257dad3a3ef7adea48aa6e576cd82de5b' \ No newline at end of file diff --git a/swh/web/tests/browse/views/test_directory.py b/swh/web/tests/browse/views/test_directory.py index bba01e74..98c22627 100644 --- a/swh/web/tests/browse/views/test_directory.py +++ b/swh/web/tests/browse/views/test_directory.py @@ -1,135 +1,118 @@ -# Copyright (C) 2017-2018 The Software Heritage developers +# Copyright (C) 2017-2019 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information -from unittest.mock import patch +import random + +from hypothesis import given -from swh.web.common.exc import BadInputExc, NotFoundExc from swh.web.common.utils import reverse, get_swh_persistent_id from swh.web.common.utils import gen_path_info -from swh.web.tests.testcase import WebTestCase - -from .data.directory_test_data import ( - stub_root_directory_sha1, stub_root_directory_data, - stub_sub_directory_path, stub_sub_directory_data +from swh.web.tests.strategies import ( + directory, directory_with_subdirs, invalid_sha1, + unknown_directory ) +from swh.web.tests.testcase import WebTestCase class SwhBrowseDirectoryTest(WebTestCase): def directory_view(self, root_directory_sha1, directory_entries, path=None): dirs = [e for e in directory_entries if e['type'] in ('dir', 'rev')] files = [e for e in directory_entries if e['type'] == 'file'] url_args = {'sha1_git': root_directory_sha1} if path: url_args['path'] = path url = reverse('browse-directory', url_args=url_args) root_dir_url = reverse('browse-directory', url_args={'sha1_git': root_directory_sha1}) resp = self.client.get(url) self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/directory.html') self.assertContains(resp, '' + root_directory_sha1[:7] + '') self.assertContains(resp, '', count=len(dirs)) self.assertContains(resp, '', count=len(files)) for d in dirs: if d['type'] == 'rev': dir_url = reverse('browse-revision', url_args={'sha1_git': d['target']}) else: dir_path = d['name'] if path: dir_path = "%s/%s" % (path, d['name']) dir_url = reverse('browse-directory', url_args={'sha1_git': root_directory_sha1, 'path': dir_path}) self.assertContains(resp, dir_url) for f in files: file_path = "%s/%s" % (root_directory_sha1, f['name']) if path: file_path = "%s/%s/%s" % (root_directory_sha1, path, f['name']) query_string = 'sha1_git:' + f['target'] file_url = reverse('browse-content', url_args={'query_string': query_string}, query_params={'path': file_path}) self.assertContains(resp, file_url) path_info = gen_path_info(path) self.assertContains(resp, '
  • ', count=len(path_info)+1) self.assertContains(resp, '%s' % (root_dir_url, root_directory_sha1[:7])) for p in path_info: dir_url = reverse('browse-directory', url_args={'sha1_git': root_directory_sha1, 'path': p['path']}) self.assertContains(resp, '%s' % (dir_url, p['name'])) self.assertContains(resp, 'vault-cook-directory') swh_dir_id = get_swh_persistent_id('directory', directory_entries[0]['dir_id']) # noqa swh_dir_id_url = reverse('browse-swh-id', url_args={'swh_id': swh_dir_id}) self.assertContains(resp, swh_dir_id) self.assertContains(resp, swh_dir_id_url) - @patch('swh.web.browse.utils.service') - def test_root_directory_view(self, mock_service): - mock_service.lookup_directory.return_value = \ - stub_root_directory_data + @given(directory()) + def test_root_directory_view(self, directory): + self.directory_view(directory, self.directory_ls(directory)) - self.directory_view(stub_root_directory_sha1, stub_root_directory_data) + @given(directory_with_subdirs()) + def test_sub_directory_view(self, directory): + dir_content = self.directory_ls(directory) + subdir = random.choice([e for e in dir_content if e['type'] == 'dir']) + subdir_content = self.directory_ls(subdir['target']) + self.directory_view(directory, subdir_content, subdir['name']) - @patch('swh.web.browse.utils.service') - @patch('swh.web.browse.views.directory.service') - def test_sub_directory_view(self, mock_directory_service, - mock_utils_service): - mock_utils_service.lookup_directory.return_value = \ - stub_sub_directory_data - mock_directory_service.lookup_directory_with_path.return_value = \ - {'target': stub_sub_directory_data[0]['dir_id'], - 'type': 'dir'} - - self.directory_view(stub_root_directory_sha1, stub_sub_directory_data, - stub_sub_directory_path) - - @patch('swh.web.browse.utils.service') - @patch('swh.web.browse.views.directory.service') - def test_directory_request_errors(self, mock_directory_service, - mock_utils_service): - - mock_utils_service.lookup_directory.side_effect = \ - BadInputExc('directory not found') + @given(invalid_sha1(), unknown_directory()) + def test_directory_request_errors(self, invalid_sha1, unknown_directory): dir_url = reverse('browse-directory', - url_args={'sha1_git': '1253456'}) + url_args={'sha1_git': invalid_sha1}) resp = self.client.get(dir_url) self.assertEqual(resp.status_code, 400) self.assertTemplateUsed('browse/error.html') - mock_utils_service.lookup_directory.side_effect = \ - NotFoundExc('directory not found') - dir_url = reverse('browse-directory', - url_args={'sha1_git': '1253456'}) + url_args={'sha1_git': unknown_directory}) resp = self.client.get(dir_url) self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('browse/error.html') diff --git a/swh/web/tests/strategies.py b/swh/web/tests/strategies.py index e8087a6d..829c6e60 100644 --- a/swh/web/tests/strategies.py +++ b/swh/web/tests/strategies.py @@ -1,501 +1,511 @@ # Copyright (C) 2018-2019 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import random from collections import defaultdict from datetime import datetime from hypothesis import settings, assume from hypothesis.strategies import ( just, sampled_from, lists, composite, datetimes, integers, binary, text, characters ) from swh.model.hashutil import hash_to_hex, hash_to_bytes from swh.model.identifiers import directory_identifier from swh.storage.algos.revisions_walker import get_revisions_walker from swh.storage.tests.algos.test_snapshot import ( # noqa origins as new_origin_strategy, snapshots as new_snapshot ) from swh.web.tests.data import get_tests_data # Module dedicated to the generation of input data for tests through # the use of hypothesis. # Some of these data are sampled from a test archive created and populated # in the swh.web.tests.data module. # Set the swh-web hypothesis profile if none has been explicitly set hypothesis_default_settings = settings.get_profile('default') if repr(settings()) == repr(hypothesis_default_settings): settings.load_profile('swh-web') # Import tests data tests_data = get_tests_data() storage = tests_data['storage'] # The following strategies exploit the hypothesis capabilities def _known_swh_object(object_type): return sampled_from(tests_data[object_type]) def sha1(): """ Hypothesis strategy returning a valid hexadecimal sha1 value. """ return binary( min_size=20, max_size=20).filter( lambda s: int.from_bytes(s, byteorder='little')).map(hash_to_hex) def invalid_sha1(): """ Hypothesis strategy returning an invalid sha1 representation. """ return binary( min_size=50, max_size=50).filter( lambda s: int.from_bytes(s, byteorder='little')).map(hash_to_hex) def sha256(): """ Hypothesis strategy returning a valid hexadecimal sha256 value. """ return binary( min_size=32, max_size=32).filter( lambda s: int.from_bytes(s, byteorder='little')).map(hash_to_hex) def content(): """ Hypothesis strategy returning a random content ingested into the test archive. """ return _known_swh_object('contents') def contents(): """ Hypothesis strategy returning random contents ingested into the test archive. """ return lists(content(), min_size=2, max_size=8) def content_text(): """ Hypothesis strategy returning random textual contents ingested into the test archive. """ return content().filter(lambda c: c['mimetype'].startswith('text/')) def content_text_non_utf8(): """ Hypothesis strategy returning random textual contents not encoded to UTF-8 ingested into the test archive. """ return content().filter(lambda c: c['mimetype'].startswith('text/') and c['encoding'] not in ('utf-8', 'us-ascii')) def content_text_no_highlight(): """ Hypothesis strategy returning random textual contents with no detected programming language to highlight ingested into the test archive. """ return content().filter(lambda c: c['mimetype'].startswith('text/') and c['hljs-language'] == 'nohighlight') def content_image_type(): """ Hypothesis strategy returning random image contents ingested into the test archive. """ return content().filter(lambda c: c['mimetype'].startswith('image/')) @composite def new_content(draw): blake2s256_hex = draw(sha256()) sha1_hex = draw(sha1()) sha1_git_hex = draw(sha1()) sha256_hex = draw(sha256()) assume(sha1_hex != sha1_git_hex) assume(blake2s256_hex != sha256_hex) return { 'blake2S256': blake2s256_hex, 'sha1': sha1_hex, 'sha1_git': sha1_git_hex, 'sha256': sha256_hex } def unknown_content(): """ Hypothesis strategy returning a random content not ingested into the test archive. """ return new_content().filter( lambda c: next(storage.content_get( [hash_to_bytes(c['sha1'])])) is None) def unknown_contents(): """ Hypothesis strategy returning random contents not ingested into the test archive. """ return lists(unknown_content(), min_size=2, max_size=8) def directory(): """ Hypothesis strategy returning a random directory ingested into the test archive. """ return _known_swh_object('directories') +def directory_with_subdirs(): + """ + Hypothesis strategy returning a random directory containing + sub directories ingested into the test archive. + """ + return directory().filter( + lambda d: any([e['type'] == 'dir' + for e in list(storage.directory_ls(hash_to_bytes(d)))])) + + def empty_directory(): """ Hypothesis strategy returning the empty directory ingested into the test archive. """ return just(directory_identifier({'entries': []})) def unknown_directory(): """ Hypothesis strategy returning a random directory not ingested into the test archive. """ return sha1().filter( lambda s: len(list(storage.directory_missing([hash_to_bytes(s)]))) > 0) def origin(): """ Hypothesis strategy returning a random origin ingested into the test archive. """ return _known_swh_object('origins') def origin_with_multiple_visits(): """ Hypothesis strategy returning a random origin ingested into the test archive. """ ret = [] for origin in tests_data['origins']: visits = list(storage.origin_visit_get(origin['id'])) if len(visits) > 1: ret.append(origin) return sampled_from(ret) def unknown_origin_id(): """ Hypothesis strategy returning a random origin id not ingested into the test archive. """ return integers(min_value=1000000) def new_origin(): """ Hypothesis strategy returning a random origin not ingested into the test archive. """ return new_origin_strategy().filter( lambda origin: storage.origin_get(origin) is None) def new_origins(nb_origins=None): """ Hypothesis strategy returning random origins not ingested into the test archive. """ min_size = nb_origins if nb_origins is not None else 2 max_size = nb_origins if nb_origins is not None else 8 size = random.randint(min_size, max_size) return lists(new_origin(), min_size=size, max_size=size, unique_by=lambda o: tuple(sorted(o.items()))) def visit_dates(nb_dates=None): """ Hypothesis strategy returning a list of visit dates. """ min_size = nb_dates if nb_dates else 2 max_size = nb_dates if nb_dates else 8 return lists(datetimes(min_value=datetime(2015, 1, 1, 0, 0), max_value=datetime(2018, 12, 31, 0, 0)), min_size=min_size, max_size=max_size, unique=True).map(sorted) def release(): """ Hypothesis strategy returning a random release ingested into the test archive. """ return _known_swh_object('releases') def unknown_release(): """ Hypothesis strategy returning a random revision not ingested into the test archive. """ return sha1().filter( lambda s: next(storage.release_get([s])) is None) def revision(): """ Hypothesis strategy returning a random revision ingested into the test archive. """ return _known_swh_object('revisions') def unknown_revision(): """ Hypothesis strategy returning a random revision not ingested into the test archive. """ return sha1().filter( lambda s: next(storage.revision_get([hash_to_bytes(s)])) is None) @composite def new_person(draw): """ Hypothesis strategy returning random raw swh person data. """ name = draw(text(min_size=5, max_size=30, alphabet=characters(min_codepoint=0, max_codepoint=255))) email = '%s@company.org' % name return { 'name': name.encode(), 'email': email.encode(), 'fullname': ('%s <%s>' % (name, email)).encode() } @composite def new_swh_date(draw): """ Hypothesis strategy returning random raw swh date data. """ timestamp = draw( datetimes(min_value=datetime(2015, 1, 1, 0, 0), max_value=datetime(2018, 12, 31, 0, 0)).map( lambda d: int(d.timestamp()))) return { 'timestamp': timestamp, 'offset': 0, 'negative_utc': False, } @composite def new_revision(draw): """ Hypothesis strategy returning random raw swh revision data not ingested into the test archive. """ return { 'id': draw(unknown_revision().map(hash_to_bytes)), 'directory': draw(sha1().map(hash_to_bytes)), 'author': draw(new_person()), 'committer': draw(new_person()), 'message': draw( text(min_size=20, max_size=100).map(lambda t: t.encode())), 'date': draw(new_swh_date()), 'committer_date': draw(new_swh_date()), 'synthetic': False, 'type': 'git', 'parents': [], 'metadata': [], } def revisions(): """ Hypothesis strategy returning random revisions ingested into the test archive. """ return lists(revision(), min_size=2, max_size=8) def unknown_revisions(): """ Hypothesis strategy returning random revisions not ingested into the test archive. """ return lists(unknown_revision(), min_size=2, max_size=8) def snapshot(): """ Hypothesis strategy returning a random snapshot ingested into the test archive. """ return _known_swh_object('snapshots') def new_snapshots(nb_snapshots=None): min_size = nb_snapshots if nb_snapshots else 2 max_size = nb_snapshots if nb_snapshots else 8 return lists(new_snapshot(min_size=2, max_size=10, only_objects=True), min_size=min_size, max_size=max_size) def unknown_snapshot(): """ Hypothesis strategy returning a random revision not ingested into the test archive. """ return sha1().filter( lambda s: storage.snapshot_get(hash_to_bytes(s)) is None) def person(): """ Hypothesis strategy returning a random person ingested into the test archive. """ return _known_swh_object('persons') def unknown_person(): """ Hypothesis strategy returning a random person not ingested into the test archive. """ persons = tests_data['persons'] return integers(min_value=max(persons)+1) def _get_origin_dfs_revisions_walker(): origin = random.choice(tests_data['origins'][:-1]) snapshot = storage.snapshot_get_latest(origin['id']) head = snapshot['branches'][b'HEAD']['target'] return get_revisions_walker('dfs', storage, head) def ancestor_revisions(): """ Hypothesis strategy returning a pair of revisions ingested into the test archive with an ancestor relation. """ # get a dfs revisions walker for one of the origins # loaded into the test archive revisions_walker = _get_origin_dfs_revisions_walker() master_revisions = [] children = defaultdict(list) init_rev_found = False # get revisions only authored in the master branch for rev in revisions_walker: for rev_p in rev['parents']: children[rev_p].append(rev['id']) if not init_rev_found: master_revisions.append(rev) if not rev['parents']: init_rev_found = True # head revision root_rev = master_revisions[0] # pick a random revision, different from head, only authored # in the master branch ancestor_rev_idx = random.choice(list(range(1, len(master_revisions)-1))) ancestor_rev = master_revisions[ancestor_rev_idx] ancestor_child_revs = children[ancestor_rev['id']] return just({ 'sha1_git_root': hash_to_hex(root_rev['id']), 'sha1_git': hash_to_hex(ancestor_rev['id']), 'children': [hash_to_hex(r) for r in ancestor_child_revs] }) def non_ancestor_revisions(): """ Hypothesis strategy returning a pair of revisions ingested into the test archive with no ancestor relation. """ # get a dfs revisions walker for one of the origins # loaded into the test archive revisions_walker = _get_origin_dfs_revisions_walker() merge_revs = [] children = defaultdict(list) # get all merge revisions for rev in revisions_walker: if len(rev['parents']) > 1: merge_revs.append(rev) for rev_p in rev['parents']: children[rev_p].append(rev['id']) # find a merge revisions whose parents have a unique child revision random.shuffle(merge_revs) selected_revs = None for merge_rev in merge_revs: if all(len(children[rev_p]) == 1 for rev_p in merge_rev['parents']): selected_revs = merge_rev['parents'] return just({ 'sha1_git_root': hash_to_hex(selected_revs[0]), 'sha1_git': hash_to_hex(selected_revs[1]) }) # The following strategies returns data specific to some tests # that can not be generated and thus are hardcoded. def contents_with_ctags(): """ Hypothesis strategy returning contents ingested into the test archive. Those contents are ctags compatible, that is running ctags on those lay results. """ return just({ 'sha1s': ['0ab37c02043ebff946c1937523f60aadd0844351', '15554cf7608dde6bfefac7e3d525596343a85b6f', '2ce837f1489bdfb8faf3ebcc7e72421b5bea83bd', '30acd0b47fc25e159e27a980102ddb1c4bea0b95', '4f81f05aaea3efb981f9d90144f746d6b682285b', '5153aa4b6e4455a62525bc4de38ed0ff6e7dd682', '59d08bafa6a749110dfb65ba43a61963d5a5bf9f', '7568285b2d7f31ae483ae71617bd3db873deaa2c', '7ed3ee8e94ac52ba983dd7690bdc9ab7618247b4', '8ed7ef2e7ff9ed845e10259d08e4145f1b3b5b03', '9b3557f1ab4111c8607a4f2ea3c1e53c6992916c', '9c20da07ed14dc4fcd3ca2b055af99b2598d8bdd', 'c20ceebd6ec6f7a19b5c3aebc512a12fbdc9234b', 'e89e55a12def4cd54d5bff58378a3b5119878eb7', 'e8c0654fe2d75ecd7e0b01bee8a8fc60a130097e', 'eb6595e559a1d34a2b41e8d4835e0e4f98a5d2b5'], 'symbol_name': 'ABS' }) def revision_with_submodules(): """ Hypothesis strategy returning a revision that is known to point to a directory with revision entries (aka git submodule) """ return just({ 'rev_sha1_git': 'ffcb69001f3f6745dfd5b48f72ab6addb560e234', 'rev_dir_sha1_git': 'd92a21446387fa28410e5a74379c934298f39ae2', 'rev_dir_rev_path': 'libtess2' })