mirror of
https://github.com/sartography/cr-connect-workflow.git
synced 2025-02-23 13:18:35 +00:00
Merge branch 'dev' into email-data-script-487
This commit is contained in:
commit
24932072dc
459
Pipfile.lock
generated
459
Pipfile.lock
generated
@ -25,11 +25,11 @@
|
||||
},
|
||||
"alembic": {
|
||||
"hashes": [
|
||||
"sha256:bc5bdf03d1b9814ee4d72adc0b19df2123f6c50a60c1ea761733f3640feedb8d",
|
||||
"sha256:d0c580041f9f6487d5444df672a83da9be57398f39d6c1802bbedec6fefbeef6"
|
||||
"sha256:9d33f3ff1488c4bfab1e1a6dfebbf085e8a8e1a3e047a43ad29ad1f67f012a1d",
|
||||
"sha256:e3cab9e59778b3b6726bb2da9ced451c6622d558199fd3ef914f3b1e8f4ef704"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.7.3"
|
||||
"version": "==1.7.4"
|
||||
},
|
||||
"amqp": {
|
||||
"hashes": [
|
||||
@ -187,9 +187,11 @@
|
||||
},
|
||||
"click-didyoumean": {
|
||||
"hashes": [
|
||||
"sha256:112229485c9704ff51362fe34b2d4f0b12fc71cc20f6d2b3afabed4b8bfa6aeb"
|
||||
"sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667",
|
||||
"sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"
|
||||
],
|
||||
"version": "==0.0.3"
|
||||
"markers": "python_version < '4' and python_full_version >= '3.6.2'",
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"click-plugins": {
|
||||
"hashes": [
|
||||
@ -240,69 +242,52 @@
|
||||
},
|
||||
"coverage": {
|
||||
"hashes": [
|
||||
"sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c",
|
||||
"sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6",
|
||||
"sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45",
|
||||
"sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a",
|
||||
"sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03",
|
||||
"sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529",
|
||||
"sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a",
|
||||
"sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a",
|
||||
"sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2",
|
||||
"sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6",
|
||||
"sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759",
|
||||
"sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53",
|
||||
"sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a",
|
||||
"sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4",
|
||||
"sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff",
|
||||
"sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502",
|
||||
"sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793",
|
||||
"sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb",
|
||||
"sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905",
|
||||
"sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821",
|
||||
"sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b",
|
||||
"sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81",
|
||||
"sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0",
|
||||
"sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b",
|
||||
"sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3",
|
||||
"sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184",
|
||||
"sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701",
|
||||
"sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a",
|
||||
"sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82",
|
||||
"sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638",
|
||||
"sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5",
|
||||
"sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083",
|
||||
"sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6",
|
||||
"sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90",
|
||||
"sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465",
|
||||
"sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a",
|
||||
"sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3",
|
||||
"sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e",
|
||||
"sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066",
|
||||
"sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf",
|
||||
"sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b",
|
||||
"sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae",
|
||||
"sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669",
|
||||
"sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873",
|
||||
"sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b",
|
||||
"sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6",
|
||||
"sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb",
|
||||
"sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160",
|
||||
"sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c",
|
||||
"sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079",
|
||||
"sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d",
|
||||
"sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"
|
||||
"sha256:08fd55d2e00dac4c18a2fa26281076035ec86e764acdc198b9185ce749ada58f",
|
||||
"sha256:11ce082eb0f7c2bbfe96f6c8bcc3a339daac57de4dc0f3186069ec5c58da911c",
|
||||
"sha256:17983f6ccc47f4864fd16d20ff677782b23d1207bf222d10e4d676e4636b0872",
|
||||
"sha256:25df2bc53a954ba2ccf230fa274d1de341f6aa633d857d75e5731365f7181749",
|
||||
"sha256:274a612f67f931307706b60700f1e4cf80e1d79dff6c282fc9301e4565e78724",
|
||||
"sha256:3dfb23cc180b674a11a559183dff9655beb9da03088f3fe3c4f3a6d200c86f05",
|
||||
"sha256:43bada49697a62ffa0283c7f01bbc76aac562c37d4bb6c45d56dd008d841194e",
|
||||
"sha256:4865dc4a7a566147cbdc2b2f033a6cccc99a7dcc89995137765c384f6c73110b",
|
||||
"sha256:581fddd2f883379bd5af51da9233e0396b6519f3d3eeae4fb88867473be6d56e",
|
||||
"sha256:5c191e01b23e760338f19d8ba2470c0dad44c8b45e41ac043b2db84efc62f695",
|
||||
"sha256:6e216e4021c934246c308fd3e0d739d9fa8a3f4ea414f584ab90ef9c1592f282",
|
||||
"sha256:72f8c99f1527c5a8ee77c890ea810e26b39fd0b4c2dffc062e20a05b2cca60ef",
|
||||
"sha256:7593a49300489d064ebb6c58539f52cbbc4a2e6a4385de5e92cae1563f88a425",
|
||||
"sha256:7844a8c6a0fee401edbf578713c2473e020759267c40261b294036f9d3eb6a2d",
|
||||
"sha256:7af2f8e7bb54ace984de790e897f858e88068d8fbc46c9490b7c19c59cf51822",
|
||||
"sha256:7dbda34e8e26bd86606ba8a9c13ccb114802e01758a3d0a75652ffc59a573220",
|
||||
"sha256:82b58d37c47d93a171be9b5744bcc96a0012cbf53d5622b29a49e6be2097edd7",
|
||||
"sha256:8305e14112efb74d0b5fec4df6e41cafde615c2392a7e51c84013cafe945842c",
|
||||
"sha256:8426fec5ad5a6e8217921716b504e9b6e1166dc147e8443b4855e329db686282",
|
||||
"sha256:88f1810eb942e7063d051d87aaaa113eb5fd5a7fd2cda03a972de57695b8bb1a",
|
||||
"sha256:8da0c4a26a831b392deaba5fdd0cd7838d173b47ce2ec3d0f37be630cb09ef6e",
|
||||
"sha256:a9dbfcbc56d8de5580483cf2caff6a59c64d3e88836cbe5fb5c20c05c29a8808",
|
||||
"sha256:aa5d4d43fa18cc9d0c6e02a83de0b9729b5451a9066574bd276481474f0a53ab",
|
||||
"sha256:adb0f4c3c8ba8104378518a1954cbf3d891a22c13fd0e0bf135391835f44f288",
|
||||
"sha256:b4ee5815c776dfa3958ba71c7cd4cdd8eb40d79358a18352feb19562fe4408c4",
|
||||
"sha256:b5dd5ae0a9cd55d71f1335c331e9625382239b8cede818fb62d8d2702336dbf8",
|
||||
"sha256:b78dd3eeb8f5ff26d2113c41836bac04a9ea91be54c346826b54a373133c8c53",
|
||||
"sha256:bea681309bdd88dd1283a8ba834632c43da376d9bce05820826090aad80c0126",
|
||||
"sha256:befb5ffa9faabef6dadc42622c73de168001425258f0b7e402a2934574e7a04b",
|
||||
"sha256:d795a2c92fe8cb31f6e9cd627ee4f39b64eb66bf47d89d8fcf7cb3d17031c887",
|
||||
"sha256:d82cbef1220703ce56822be7fbddb40736fc1a928ac893472df8aff7421ae0aa",
|
||||
"sha256:e63490e8a6675cee7a71393ee074586f7eeaf0e9341afd006c5d6f7eec7c16d7",
|
||||
"sha256:e735ab8547d8a1fe8e58dd765d6f27ac539b395f52160d767b7189f379f9be7a",
|
||||
"sha256:fa816e97cfe1f691423078dffa39a18106c176f28008db017b3ce3e947c34aa5",
|
||||
"sha256:fff04bfefb879edcf616f1ce5ea6f4a693b5976bdc5e163f8464f349c25b59f0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.5"
|
||||
"version": "==6.0"
|
||||
},
|
||||
"dateparser": {
|
||||
"hashes": [
|
||||
"sha256:159cc4e01a593706a15cd4e269a0b3345edf3aef8bf9278a57dac8adf5bf1e4a",
|
||||
"sha256:17202df32c7a36e773136ff353aa3767e987f8b3e27374c39fd21a30a803d6f8"
|
||||
"sha256:faa2b97f51f3b5ff1ba2f17be90de2b733fb6191f89b4058787473e8202f3044",
|
||||
"sha256:fec344db1f73d005182e214c0ff27313c748bbe0c1638ce9d48a809ddfdab2a0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.0"
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"deprecated": {
|
||||
"hashes": [
|
||||
@ -328,11 +313,11 @@
|
||||
},
|
||||
"docxtpl": {
|
||||
"hashes": [
|
||||
"sha256:84b5b35eca090f03768109440ad8e4c5040d8614e2c5bdc807a7ca55d23d7018",
|
||||
"sha256:fae3c2f6afcb11ceb85dace09a99d4d64d604623653d66b754e90fca150e77b3"
|
||||
"sha256:c90ca0b7251d3aa20bb5b67d1b6d4dcd546cb0c56aa080f6733656622bd086e1",
|
||||
"sha256:e8d3dba9c9638f8d3212187e6b8cd1dbcc87f4fb34a436873e4e86a530602b99"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.12.0"
|
||||
"version": "==0.14.2"
|
||||
},
|
||||
"et-xmlfile": {
|
||||
"hashes": [
|
||||
@ -420,59 +405,59 @@
|
||||
},
|
||||
"greenlet": {
|
||||
"hashes": [
|
||||
"sha256:04e1849c88aa56584d4a0a6e36af5ec7cc37993fdc1fda72b56aa1394a92ded3",
|
||||
"sha256:05e72db813c28906cdc59bd0da7c325d9b82aa0b0543014059c34c8c4ad20e16",
|
||||
"sha256:07e6d88242e09b399682b39f8dfa1e7e6eca66b305de1ff74ed9eb1a7d8e539c",
|
||||
"sha256:090126004c8ab9cd0787e2acf63d79e80ab41a18f57d6448225bbfcba475034f",
|
||||
"sha256:1796f2c283faab2b71c67e9b9aefb3f201fdfbee5cb55001f5ffce9125f63a45",
|
||||
"sha256:2f89d74b4f423e756a018832cd7a0a571e0a31b9ca59323b77ce5f15a437629b",
|
||||
"sha256:34e6675167a238bede724ee60fe0550709e95adaff6a36bcc97006c365290384",
|
||||
"sha256:3e594015a2349ec6dcceda9aca29da8dc89e85b56825b7d1f138a3f6bb79dd4c",
|
||||
"sha256:3f8fc59bc5d64fa41f58b0029794f474223693fd00016b29f4e176b3ee2cfd9f",
|
||||
"sha256:3fc6a447735749d651d8919da49aab03c434a300e9f0af1c886d560405840fd1",
|
||||
"sha256:40abb7fec4f6294225d2b5464bb6d9552050ded14a7516588d6f010e7e366dcc",
|
||||
"sha256:44556302c0ab376e37939fd0058e1f0db2e769580d340fb03b01678d1ff25f68",
|
||||
"sha256:476ba9435afaead4382fbab8f1882f75e3fb2285c35c9285abb3dd30237f9142",
|
||||
"sha256:4870b018ca685ff573edd56b93f00a122f279640732bb52ce3a62b73ee5c4a92",
|
||||
"sha256:4adaf53ace289ced90797d92d767d37e7cdc29f13bd3830c3f0a561277a4ae83",
|
||||
"sha256:4eae94de9924bbb4d24960185363e614b1b62ff797c23dc3c8a7c75bbb8d187e",
|
||||
"sha256:5317701c7ce167205c0569c10abc4bd01c7f4cf93f642c39f2ce975fa9b78a3c",
|
||||
"sha256:5c3b735ccf8fc8048664ee415f8af5a3a018cc92010a0d7195395059b4b39b7d",
|
||||
"sha256:5cde7ee190196cbdc078511f4df0be367af85636b84d8be32230f4871b960687",
|
||||
"sha256:655ab836324a473d4cd8cf231a2d6f283ed71ed77037679da554e38e606a7117",
|
||||
"sha256:6ce9d0784c3c79f3e5c5c9c9517bbb6c7e8aa12372a5ea95197b8a99402aa0e6",
|
||||
"sha256:6e0696525500bc8aa12eae654095d2260db4dc95d5c35af2b486eae1bf914ccd",
|
||||
"sha256:75ff270fd05125dce3303e9216ccddc541a9e072d4fc764a9276d44dee87242b",
|
||||
"sha256:8039f5fe8030c43cd1732d9a234fdcbf4916fcc32e21745ca62e75023e4d4649",
|
||||
"sha256:84488516639c3c5e5c0e52f311fff94ebc45b56788c2a3bfe9cf8e75670f4de3",
|
||||
"sha256:84782c80a433d87530ae3f4b9ed58d4a57317d9918dfcc6a59115fa2d8731f2c",
|
||||
"sha256:8ddb38fb6ad96c2ef7468ff73ba5c6876b63b664eebb2c919c224261ae5e8378",
|
||||
"sha256:98b491976ed656be9445b79bc57ed21decf08a01aaaf5fdabf07c98c108111f6",
|
||||
"sha256:990e0f5e64bcbc6bdbd03774ecb72496224d13b664aa03afd1f9b171a3269272",
|
||||
"sha256:9b02e6039eafd75e029d8c58b7b1f3e450ca563ef1fe21c7e3e40b9936c8d03e",
|
||||
"sha256:a11b6199a0b9dc868990456a2667167d0ba096c5224f6258e452bfbe5a9742c5",
|
||||
"sha256:a414f8e14aa7bacfe1578f17c11d977e637d25383b6210587c29210af995ef04",
|
||||
"sha256:a91ee268f059583176c2c8b012a9fce7e49ca6b333a12bbc2dd01fc1a9783885",
|
||||
"sha256:ac991947ca6533ada4ce7095f0e28fe25d5b2f3266ad5b983ed4201e61596acf",
|
||||
"sha256:b050dbb96216db273b56f0e5960959c2b4cb679fe1e58a0c3906fa0a60c00662",
|
||||
"sha256:b97a807437b81f90f85022a9dcfd527deea38368a3979ccb49d93c9198b2c722",
|
||||
"sha256:bad269e442f1b7ffa3fa8820b3c3aa66f02a9f9455b5ba2db5a6f9eea96f56de",
|
||||
"sha256:bf3725d79b1ceb19e83fb1aed44095518c0fcff88fba06a76c0891cfd1f36837",
|
||||
"sha256:c0f22774cd8294078bdf7392ac73cf00bfa1e5e0ed644bd064fdabc5f2a2f481",
|
||||
"sha256:c1862f9f1031b1dee3ff00f1027fcd098ffc82120f43041fe67804b464bbd8a7",
|
||||
"sha256:c8d4ed48eed7414ccb2aaaecbc733ed2a84c299714eae3f0f48db085342d5629",
|
||||
"sha256:cf31e894dabb077a35bbe6963285d4515a387ff657bd25b0530c7168e48f167f",
|
||||
"sha256:d15cb6f8706678dc47fb4e4f8b339937b04eda48a0af1cca95f180db552e7663",
|
||||
"sha256:dfcb5a4056e161307d103bc013478892cfd919f1262c2bb8703220adcb986362",
|
||||
"sha256:e02780da03f84a671bb4205c5968c120f18df081236d7b5462b380fd4f0b497b",
|
||||
"sha256:e2002a59453858c7f3404690ae80f10c924a39f45f6095f18a985a1234c37334",
|
||||
"sha256:e22a82d2b416d9227a500c6860cf13e74060cf10e7daf6695cbf4e6a94e0eee4",
|
||||
"sha256:e41f72f225192d5d4df81dad2974a8943b0f2d664a2a5cfccdf5a01506f5523c",
|
||||
"sha256:f253dad38605486a4590f9368ecbace95865fea0f2b66615d121ac91fd1a1563",
|
||||
"sha256:fddfb31aa2ac550b938d952bca8a87f1db0f8dc930ffa14ce05b5c08d27e7fd1"
|
||||
"sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711",
|
||||
"sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd",
|
||||
"sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073",
|
||||
"sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708",
|
||||
"sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67",
|
||||
"sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23",
|
||||
"sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1",
|
||||
"sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08",
|
||||
"sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd",
|
||||
"sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa",
|
||||
"sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8",
|
||||
"sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40",
|
||||
"sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab",
|
||||
"sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6",
|
||||
"sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc",
|
||||
"sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b",
|
||||
"sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e",
|
||||
"sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963",
|
||||
"sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3",
|
||||
"sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d",
|
||||
"sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d",
|
||||
"sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28",
|
||||
"sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3",
|
||||
"sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e",
|
||||
"sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c",
|
||||
"sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d",
|
||||
"sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0",
|
||||
"sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497",
|
||||
"sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee",
|
||||
"sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713",
|
||||
"sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58",
|
||||
"sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a",
|
||||
"sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06",
|
||||
"sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88",
|
||||
"sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4",
|
||||
"sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5",
|
||||
"sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c",
|
||||
"sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a",
|
||||
"sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1",
|
||||
"sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43",
|
||||
"sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627",
|
||||
"sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b",
|
||||
"sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168",
|
||||
"sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d",
|
||||
"sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5",
|
||||
"sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478",
|
||||
"sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf",
|
||||
"sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce",
|
||||
"sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c",
|
||||
"sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b"
|
||||
],
|
||||
"markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
|
||||
"version": "==1.1.1"
|
||||
"version": "==1.1.2"
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
@ -505,6 +490,14 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15",
|
||||
"sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"
|
||||
],
|
||||
"markers": "python_version < '3.9'",
|
||||
"version": "==4.8.1"
|
||||
},
|
||||
"importlib-resources": {
|
||||
"hashes": [
|
||||
"sha256:2480d8e07d1890056cb53c96e3de44fead9c62f2ba949b0f2e4c4345f4afa977",
|
||||
@ -989,10 +982,10 @@
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da",
|
||||
"sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"
|
||||
"sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c",
|
||||
"sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"
|
||||
],
|
||||
"version": "==2021.1"
|
||||
"version": "==2021.3"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
@ -1039,49 +1032,49 @@
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:0628ed7d6334e8f896f882a5c1240de8c4d9b0dd7c7fb8e9f4692f5684b7d656",
|
||||
"sha256:09eb62654030f39f3ba46bc6726bea464069c29d00a9709e28c9ee9623a8da4a",
|
||||
"sha256:0bba1f6df4eafe79db2ecf38835c2626dbd47911e0516f6962c806f83e7a99ae",
|
||||
"sha256:10a7a9cbe30bd90b7d9a1b4749ef20e13a3528e4215a2852be35784b6bd070f0",
|
||||
"sha256:17310b181902e0bb42b29c700e2c2346b8d81f26e900b1328f642e225c88bce1",
|
||||
"sha256:1e8d1898d4fb817120a5f684363b30108d7b0b46c7261264b100d14ec90a70e7",
|
||||
"sha256:2054dea683f1bda3a804fcfdb0c1c74821acb968093d0be16233873190d459e3",
|
||||
"sha256:29385c4dbb3f8b3a55ce13de6a97a3d21bd00de66acd7cdfc0b49cb2f08c906c",
|
||||
"sha256:295bc8a13554a25ad31e44c4bedabd3c3e28bba027e4feeb9bb157647a2344a7",
|
||||
"sha256:2cdb3789736f91d0b3333ac54d12a7e4f9efbc98f53cb905d3496259a893a8b3",
|
||||
"sha256:3baf3eaa41044d4ced2463fd5d23bf7bd4b03d68739c6c99a59ce1f95599a673",
|
||||
"sha256:4e61100200fa6ab7c99b61476f9f9653962ae71b931391d0264acfb4d9527d9c",
|
||||
"sha256:6266fde576e12357b25096351aac2b4b880b0066263e7bc7a9a1b4307991bb0e",
|
||||
"sha256:650c4f1fc4273f4e783e1d8e8b51a3e2311c2488ba0fcae6425b1e2c248a189d",
|
||||
"sha256:658e3477676009083422042c4bac2bdad77b696e932a3de001c42cc046f8eda2",
|
||||
"sha256:6adc1bd68f81968c9d249aab8c09cdc2cbe384bf2d2cb7f190f56875000cdc72",
|
||||
"sha256:6c4d83d21d23dd854ffbc8154cf293f4e43ba630aa9bd2539c899343d7f59da3",
|
||||
"sha256:6f74b6d8f59f3cfb8237e25c532b11f794b96f5c89a6f4a25857d85f84fbef11",
|
||||
"sha256:7783d89bd5413d183a38761fbc68279b984b9afcfbb39fa89d91f63763fbfb90",
|
||||
"sha256:7e3536f305f42ad6d31fc86636c54c7dafce8d634e56fef790fbacb59d499dd5",
|
||||
"sha256:821e10b73e0898544807a0692a276e539e5bafe0a055506a6882814b6a02c3ec",
|
||||
"sha256:835962f432bce92dc9bf22903d46c50003c8d11b1dc64084c8fae63bca98564a",
|
||||
"sha256:85c61bee5957e2d7be390392feac7e1d7abd3a49cbaed0c8cee1541b784c8561",
|
||||
"sha256:86f9931eb92e521809d4b64ec8514f18faa8e11e97d6c2d1afa1bcf6c20a8eab",
|
||||
"sha256:8a5c2250c0a74428fd5507ae8853706fdde0f23bfb62ee1ec9418eeacf216078",
|
||||
"sha256:8aec4b4da165c4a64ea80443c16e49e3b15df0f56c124ac5f2f8708a65a0eddc",
|
||||
"sha256:8c268e78d175798cd71d29114b0a1f1391c7d011995267d3b62319ec1a4ecaa1",
|
||||
"sha256:8d80087320632457aefc73f686f66139801959bf5b066b4419b92be85be3543c",
|
||||
"sha256:95e89a8558c8c48626dcffdf9c8abac26b7c251d352688e7ab9baf351e1c7da6",
|
||||
"sha256:9c371dd326289d85906c27ec2bc1dcdedd9d0be12b543d16e37bad35754bde48",
|
||||
"sha256:9c7cb25adba814d5f419733fe565f3289d6fa629ab9e0b78f6dff5fa94ab0456",
|
||||
"sha256:a731552729ee8ae9c546fb1c651c97bf5f759018fdd40d0e9b4d129e1e3a44c8",
|
||||
"sha256:aea4006b73b555fc5bdb650a8b92cf486d678afa168cf9b38402bb60bf0f9c18",
|
||||
"sha256:b0e3f59d3c772f2c3baaef2db425e6fc4149d35a052d874bb95ccfca10a1b9f4",
|
||||
"sha256:b15dc34273aefe522df25096d5d087abc626e388a28a28ac75a4404bb7668736",
|
||||
"sha256:c000635fd78400a558bd7a3c2981bb2a430005ebaa909d31e6e300719739a949",
|
||||
"sha256:c31f35a984caffb75f00a86852951a337540b44e4a22171354fb760cefa09346",
|
||||
"sha256:c50a6379763c733562b1fee877372234d271e5c78cd13ade5f25978aa06744db",
|
||||
"sha256:c94722bf403b8da744b7d0bb87e1f2529383003ceec92e754f768ef9323f69ad",
|
||||
"sha256:dcbbc9cfa147d55a577d285fd479b43103188855074552708df7acc31a476dd9",
|
||||
"sha256:fb9f5844db480e2ef9fce3a72e71122dd010ab7b2920f777966ba25f7eb63819"
|
||||
"sha256:0de8ad66b08c3e673b61981b9e3626f8784d5564f8c3928e2ad408c0eb5ac38c",
|
||||
"sha256:1f1125bc5172ab3a049bc6f4b9c0aae95a2a2001a77e6d6e4239fa3653e202b5",
|
||||
"sha256:255791523f80ea8e48e79af7120b4697ef3b74f6886995dcdb08c41f8e516be0",
|
||||
"sha256:28040e89a04b60d579c69095c509a4f6a1a5379cd865258e3a186b7105de72c6",
|
||||
"sha256:37868075eda024470bd0feab872c692ac4ee29db1e14baec103257bf6cc64346",
|
||||
"sha256:3b71213ec3bad9a5a02e049f2ec86b3d7c3e350129ae0f4e2f99c12b5da919ed",
|
||||
"sha256:3be40f720af170a6b20ddd2ad7904c58b13d2b56f6734ee5d09bbdeed2fa4816",
|
||||
"sha256:42952d325439ef223e4e9db7ee6d9087b5c68c5c15b1f9de68e990837682fc7b",
|
||||
"sha256:470f2c882f2672d8eeda8ab27992aec277c067d280b52541357e1acd7e606dae",
|
||||
"sha256:4907fb0f9b9309a5bded72343e675a252c2589a41871874feace9a05a540241e",
|
||||
"sha256:4d87459ad3ab40cd8493774f8a454b2e490d8e729e7e402a0625867a983e4e02",
|
||||
"sha256:4fa7ba9ab2eba7284e0d7d94f61df7af86015b0398e123331362270d71fab0b9",
|
||||
"sha256:5b34d2335d6aedec7dcadd3f8283b9682fadad8b9b008da8788d2fce76125ebe",
|
||||
"sha256:6348a7ab2a502cbdd0b7fd0496d614007489adb7361956b38044d1d588e66e04",
|
||||
"sha256:638e98d069b14113e8afba6a54d1ca123f712c0d105e67c1f9211b2a825ef926",
|
||||
"sha256:66696c8336a1b5d1182464f3af3427cc760118f26d0b09a2ddc16a976a4d2637",
|
||||
"sha256:78cf6a1e023caf5e9a982f5377414e1aeac55198831b852835732cfd0a0ca5ff",
|
||||
"sha256:81e125d9ba54c34579e4539a967e976a3c56150796674aec318b1b2f49251be7",
|
||||
"sha256:81fdc90f999b2147fc62e303440c424c47e5573a9b615ed5d43a5b832efcca9e",
|
||||
"sha256:87e9c489aa98f50f367fb26cc9c8908d668e9228d327644d7aa568d47e456f47",
|
||||
"sha256:8c1ad61fa024195136a6b7b89538030bd00df15f90ac177ca278df9b2386c96f",
|
||||
"sha256:9910869c472e5a6728680ca357b5846546cbbd2ab3ad5bef986ef0bc438d0aa6",
|
||||
"sha256:9925985be05d54b3d25fd6c1ea8e50ff1f7c2744c75bdc4d3b45c790afa2bcb3",
|
||||
"sha256:9a0b0db6b49da7fa37ca8eddf9f40a8dbc599bad43e64f452284f37b6c34d91c",
|
||||
"sha256:9c065d95a514a06b92a5026766d72ac91bfabf581adb5b29bc5c91d4b3ee9b83",
|
||||
"sha256:a6f08187136f11e430638c2c66e1db091105d7c2e9902489f0dbc69b44c222b4",
|
||||
"sha256:ad0517df22a97f1da20d8f1c8cb71a5d1997fa383326b81f9cf22c9dadfbdf34",
|
||||
"sha256:b345ecde37c86dd7084c62954468a4a655fd2d24fd9b237949dd07a4d0dd6f4c",
|
||||
"sha256:b55442650f541d195a535ccec33078c78a9521973fb960923da7515e9ed78fa6",
|
||||
"sha256:c2b180ed30856dfa70cfe927b0fd38e6b68198a03039abdbeb1f2029758d87e7",
|
||||
"sha256:c9e30838df7bfd20db6466fd309d9b580d32855f8e2c2e6d74cf9da27dcd9b63",
|
||||
"sha256:cae4099031d80703954c39680323dabd87a69b21262303160776aa0e55970ca0",
|
||||
"sha256:ce7b1cca6c23f19bee8dc40228d9c314d86d1e51996b86f924aca302fc8f8bf9",
|
||||
"sha256:d0861e7f6325e821d5c40514c551fd538b292f8cc3960086e73491b9c5d8291d",
|
||||
"sha256:d331f238a7accfbbe1c4cd1ba610d4c087b206353539331e32a8f05345c74aec",
|
||||
"sha256:e07049cece3462c626d650e8bf42ddbca3abf4aa08155002c28cb6d9a5a281e2",
|
||||
"sha256:e2cb7d4909ed16ed35729d38af585673f1f0833e73dfdf0c18e5be0061107b99",
|
||||
"sha256:e3770781353a4886b68ef10cec31c1f61e8e3a0be5f213c2bb15a86efd999bc4",
|
||||
"sha256:e502f8d4e5ef714bcc2c94d499684890c94239526d61fdf1096547db91ca6aa6",
|
||||
"sha256:e6f2d2f93001801296fe3ca86515eb04915472b5380d4d8752f09f25f0b9b0ed",
|
||||
"sha256:f588209d3e4797882cd238195c175290dbc501973b10a581086b5c6bcd095ffb"
|
||||
],
|
||||
"version": "==2021.9.24"
|
||||
"version": "==2021.9.30"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
@ -1183,7 +1176,7 @@
|
||||
},
|
||||
"spiffworkflow": {
|
||||
"git": "https://github.com/sartography/SpiffWorkflow",
|
||||
"ref": "d911632569d73ec5e039504005a740c3d4d50451"
|
||||
"ref": "4b4628ac2d0edc2aeec387515a26cdab373f95fb"
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"hashes": [
|
||||
@ -1293,9 +1286,54 @@
|
||||
},
|
||||
"wrapt": {
|
||||
"hashes": [
|
||||
"sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
|
||||
"sha256:04312fbf51e9dd15261228e6b4bed0c0ed5723ccf986645d2c7308511dccba35",
|
||||
"sha256:04a00cef5d1b9e0e8db997816437b436e859106283c4771a40c4de4759344765",
|
||||
"sha256:0b2cbe418beeff3aadb3afc39a67d3f5f6a3eb020ceb5f2bcf56bef14b33629a",
|
||||
"sha256:19b2c992668c9ca764899bae52987a04041ebc21859d2646db0b27e089c2fd6b",
|
||||
"sha256:1b46e4fe0f9efbfaf1ee82fc79f9cb044c69b67b181c58370440d396fe40736e",
|
||||
"sha256:21c1710f61aa95b4be83a32b6d6facbb0efdfac22dee65e1caa72a83deed7cda",
|
||||
"sha256:2d18618440df6bc072762625e9c843d32a7328347c321b89f8df3a7c4a72ce6c",
|
||||
"sha256:2f6fbea8936ba862425664fc689182a8ef50a6d88cd49f3cd073eccd3e78c930",
|
||||
"sha256:3658ae9c704906cab5865a00c1aa9e1fd3555074d1a4462fa1742d7fea8260ae",
|
||||
"sha256:3816922f0941f1637869a04e25d1e5261dfa55cc6b39c73872cbf192ea562443",
|
||||
"sha256:40fd2cebad4010787de4221ec27a650635eed3e49e4bbfa8244fc34836cc2457",
|
||||
"sha256:4f3f99bb8eed5d394bbb898c5191ed91ebf21187d52b2c45895733ae2798f373",
|
||||
"sha256:5dc6c8cfaf4ff2a4632f8f97d29f555d6951eb0f905d3d47b3fd69bddb653214",
|
||||
"sha256:6aa687da5565674c9696fafd2b8d44a04fb697ec2431af21c3def9cbedc4082a",
|
||||
"sha256:6b81913fdba96e286f0c6007eb61f0158e64a1941bfc72fee61b34a4f8f9877f",
|
||||
"sha256:6c241b4ef0744590ae0ee89305743977e478200cff961bdcc6b3d0530aea3377",
|
||||
"sha256:77fef0bfdc612f5f30e43392a9f67dddaf4f48f299421bf25f910d0f47173f3d",
|
||||
"sha256:7929ce97be2f7c49f454a6f8e014225e53cc3767fe48cce94b188de2225232ac",
|
||||
"sha256:8055f8cc9a80dc1db01f31af6399b83f597ec164f07b7251d2a1bf1c6c025190",
|
||||
"sha256:836c73f53a0cefc7ba10c6f4a0d78894cb4876f56035fe500b029e0a1ae0ffe9",
|
||||
"sha256:8a184c655bb41295a9b0c28745a1b762c0c86025e43808b7e814f9cedc6c563d",
|
||||
"sha256:8a6ba1b00d07f5a90a2d2eb1804a42e2067a6145b7745a8297664a75a8a232ba",
|
||||
"sha256:909a80ce028821c7ad01bdcaa588126825931d177cdccd00b3545818d4a195ce",
|
||||
"sha256:947a8d9d7829364e11eca88af18394713c8f98571cbc672b12545977d837f054",
|
||||
"sha256:95c9fcfc326fdd3e2fd264e808f6474ca7ffd253feb3a505ee5ceb4d78216ef7",
|
||||
"sha256:972099fa9cf4e43c255701c78ec5098c2fec4d6ea669a110b3414a158e772b0a",
|
||||
"sha256:97f016514ceac524832e7d1bd41cf928b992ebe0324d59736f84ad5f4bbe0632",
|
||||
"sha256:9d200716eb4bb1d73f47f3ccc4f98fdf979dcc82d752183828f1be2e332b6874",
|
||||
"sha256:9f839c47698052ef5c2c094e21f8a06d0828aebe52d20cdb505faa318c62e886",
|
||||
"sha256:aa637733f1d599077522f6a1f0c6c40389aa90a44cba37afcefef26f8e53d28f",
|
||||
"sha256:b0eed9b295039a619f64667f27cffbffcfc0559073d562700912ca6266bc8b28",
|
||||
"sha256:b1137e6aef3ac267c2af7d3af0266ef3f8dd1e5cde67b8eac9fa3b94e7fa0ada",
|
||||
"sha256:b41ce8ee3825634e67883dd4dab336f95d0cc9d223fb7e224dcd36d66af93694",
|
||||
"sha256:bc42803987eb46b5fc67ec9a072df15a72ee9db61e3b7dd955d82581bf141f60",
|
||||
"sha256:bd705e341baccc3d1ef20e790b1f6383bd4ae92a77ba87a86ece8189fab8793c",
|
||||
"sha256:c803526c0d3fa426e06de379b4eb56102234f2dc3c3a24a500d7962a83ca6166",
|
||||
"sha256:cb0b12b365b054bee2a53078a67df81781be0686cc3f3ab8bbdd16b2e188570a",
|
||||
"sha256:d0ae90fd60c7473e437b0dd48ae323c11f631fe47c243056f9e7505d26e8e2f6",
|
||||
"sha256:db0daf2afca9f3b3a76e96ecb5f55ba82615ec584471d7aa27c1bdeb9e3888bb",
|
||||
"sha256:e2eb4f38441b56698b4d40d48fd331e4e8a0477264785d08cbced63813d4bd29",
|
||||
"sha256:e5a0727ea56de6e9a17693589bcf913d6bf1ec49f12d4671993321f3325fda4f",
|
||||
"sha256:ec803c9d6e4ce037201132d903ff8b0dd26c9688be50ce4c77c420c076e78ff7",
|
||||
"sha256:f1e2cea943192e24070b65bda862901c02bdf7c6abcd66ef5381ad6511921067",
|
||||
"sha256:f4377eda306b488255ea4336662cd9015a902d6dc2ed77a3e4c1e3b42387453a",
|
||||
"sha256:fd5320bf61a2e8d3b46d9e183323293c9a695df8f38c98d17c45e1846758f9a9"
|
||||
],
|
||||
"version": "==1.12.1"
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==1.13.1"
|
||||
},
|
||||
"wtforms": {
|
||||
"hashes": [
|
||||
@ -1322,11 +1360,11 @@
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:1fc9641b26f3bd81069b7738b039f2819cab6e3fc3399a953e19d92cc81eff4d",
|
||||
"sha256:8dc6c4d5a809d659067cc713f76bcf42fae8ae641db12fddfa93694a15abc96b"
|
||||
"sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832",
|
||||
"sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"
|
||||
],
|
||||
"markers": "python_version < '3.10'",
|
||||
"version": "==3.5.1"
|
||||
"version": "==3.6.0"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
@ -1340,61 +1378,44 @@
|
||||
},
|
||||
"coverage": {
|
||||
"hashes": [
|
||||
"sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c",
|
||||
"sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6",
|
||||
"sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45",
|
||||
"sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a",
|
||||
"sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03",
|
||||
"sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529",
|
||||
"sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a",
|
||||
"sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a",
|
||||
"sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2",
|
||||
"sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6",
|
||||
"sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759",
|
||||
"sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53",
|
||||
"sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a",
|
||||
"sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4",
|
||||
"sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff",
|
||||
"sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502",
|
||||
"sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793",
|
||||
"sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb",
|
||||
"sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905",
|
||||
"sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821",
|
||||
"sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b",
|
||||
"sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81",
|
||||
"sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0",
|
||||
"sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b",
|
||||
"sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3",
|
||||
"sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184",
|
||||
"sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701",
|
||||
"sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a",
|
||||
"sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82",
|
||||
"sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638",
|
||||
"sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5",
|
||||
"sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083",
|
||||
"sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6",
|
||||
"sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90",
|
||||
"sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465",
|
||||
"sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a",
|
||||
"sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3",
|
||||
"sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e",
|
||||
"sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066",
|
||||
"sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf",
|
||||
"sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b",
|
||||
"sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae",
|
||||
"sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669",
|
||||
"sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873",
|
||||
"sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b",
|
||||
"sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6",
|
||||
"sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb",
|
||||
"sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160",
|
||||
"sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c",
|
||||
"sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079",
|
||||
"sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d",
|
||||
"sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"
|
||||
"sha256:08fd55d2e00dac4c18a2fa26281076035ec86e764acdc198b9185ce749ada58f",
|
||||
"sha256:11ce082eb0f7c2bbfe96f6c8bcc3a339daac57de4dc0f3186069ec5c58da911c",
|
||||
"sha256:17983f6ccc47f4864fd16d20ff677782b23d1207bf222d10e4d676e4636b0872",
|
||||
"sha256:25df2bc53a954ba2ccf230fa274d1de341f6aa633d857d75e5731365f7181749",
|
||||
"sha256:274a612f67f931307706b60700f1e4cf80e1d79dff6c282fc9301e4565e78724",
|
||||
"sha256:3dfb23cc180b674a11a559183dff9655beb9da03088f3fe3c4f3a6d200c86f05",
|
||||
"sha256:43bada49697a62ffa0283c7f01bbc76aac562c37d4bb6c45d56dd008d841194e",
|
||||
"sha256:4865dc4a7a566147cbdc2b2f033a6cccc99a7dcc89995137765c384f6c73110b",
|
||||
"sha256:581fddd2f883379bd5af51da9233e0396b6519f3d3eeae4fb88867473be6d56e",
|
||||
"sha256:5c191e01b23e760338f19d8ba2470c0dad44c8b45e41ac043b2db84efc62f695",
|
||||
"sha256:6e216e4021c934246c308fd3e0d739d9fa8a3f4ea414f584ab90ef9c1592f282",
|
||||
"sha256:72f8c99f1527c5a8ee77c890ea810e26b39fd0b4c2dffc062e20a05b2cca60ef",
|
||||
"sha256:7593a49300489d064ebb6c58539f52cbbc4a2e6a4385de5e92cae1563f88a425",
|
||||
"sha256:7844a8c6a0fee401edbf578713c2473e020759267c40261b294036f9d3eb6a2d",
|
||||
"sha256:7af2f8e7bb54ace984de790e897f858e88068d8fbc46c9490b7c19c59cf51822",
|
||||
"sha256:7dbda34e8e26bd86606ba8a9c13ccb114802e01758a3d0a75652ffc59a573220",
|
||||
"sha256:82b58d37c47d93a171be9b5744bcc96a0012cbf53d5622b29a49e6be2097edd7",
|
||||
"sha256:8305e14112efb74d0b5fec4df6e41cafde615c2392a7e51c84013cafe945842c",
|
||||
"sha256:8426fec5ad5a6e8217921716b504e9b6e1166dc147e8443b4855e329db686282",
|
||||
"sha256:88f1810eb942e7063d051d87aaaa113eb5fd5a7fd2cda03a972de57695b8bb1a",
|
||||
"sha256:8da0c4a26a831b392deaba5fdd0cd7838d173b47ce2ec3d0f37be630cb09ef6e",
|
||||
"sha256:a9dbfcbc56d8de5580483cf2caff6a59c64d3e88836cbe5fb5c20c05c29a8808",
|
||||
"sha256:aa5d4d43fa18cc9d0c6e02a83de0b9729b5451a9066574bd276481474f0a53ab",
|
||||
"sha256:adb0f4c3c8ba8104378518a1954cbf3d891a22c13fd0e0bf135391835f44f288",
|
||||
"sha256:b4ee5815c776dfa3958ba71c7cd4cdd8eb40d79358a18352feb19562fe4408c4",
|
||||
"sha256:b5dd5ae0a9cd55d71f1335c331e9625382239b8cede818fb62d8d2702336dbf8",
|
||||
"sha256:b78dd3eeb8f5ff26d2113c41836bac04a9ea91be54c346826b54a373133c8c53",
|
||||
"sha256:bea681309bdd88dd1283a8ba834632c43da376d9bce05820826090aad80c0126",
|
||||
"sha256:befb5ffa9faabef6dadc42622c73de168001425258f0b7e402a2934574e7a04b",
|
||||
"sha256:d795a2c92fe8cb31f6e9cd627ee4f39b64eb66bf47d89d8fcf7cb3d17031c887",
|
||||
"sha256:d82cbef1220703ce56822be7fbddb40736fc1a928ac893472df8aff7421ae0aa",
|
||||
"sha256:e63490e8a6675cee7a71393ee074586f7eeaf0e9341afd006c5d6f7eec7c16d7",
|
||||
"sha256:e735ab8547d8a1fe8e58dd765d6f27ac539b395f52160d767b7189f379f9be7a",
|
||||
"sha256:fa816e97cfe1f691423078dffa39a18106c176f28008db017b3ce3e947c34aa5",
|
||||
"sha256:fff04bfefb879edcf616f1ce5ea6f4a693b5976bdc5e163f8464f349c25b59f0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.5"
|
||||
"version": "==6.0"
|
||||
},
|
||||
"iniconfig": {
|
||||
"hashes": [
|
||||
|
@ -78,7 +78,7 @@ GITHUB_REPO = environ.get('GITHUB_REPO', None)
|
||||
TARGET_BRANCH = environ.get('TARGET_BRANCH', None)
|
||||
|
||||
# Email configuration
|
||||
DEFAULT_SENDER = 'askresearch@virginia.edu'
|
||||
DEFAULT_SENDER = 'uvacrconnect@virginia.edu'
|
||||
FALLBACK_EMAILS = ['askresearch@virginia.edu', 'sartographysupport@googlegroups.com']
|
||||
MAIL_DEBUG = environ.get('MAIL_DEBUG', default=True)
|
||||
MAIL_SERVER = environ.get('MAIL_SERVER', default='smtp.mailtrap.io')
|
||||
|
@ -51,18 +51,30 @@ class ApiError(Exception):
|
||||
if "task" in task.data:
|
||||
task.data.pop("task")
|
||||
|
||||
# In the unlikely event that the API error can't be serialized, try removing the task_data, as it may
|
||||
# contain some invalid data that we can't return, so we can at least get the erro rmessage.
|
||||
instance.task_data = task.data
|
||||
try:
|
||||
json.dumps(ApiErrorSchema().dump(instance))
|
||||
except TypeError as te:
|
||||
instance.task_data = {
|
||||
'task_data_hidden': 'We were unable to serialize the task data when reporting this error'}
|
||||
# Assure that there is nothing in the json data that can't be serialized.
|
||||
instance.task_data = ApiError.remove_unserializeable_from_dict(task.data)
|
||||
|
||||
app.logger.error(message, exc_info=True)
|
||||
return instance
|
||||
|
||||
@staticmethod
|
||||
def remove_unserializeable_from_dict(my_dict):
|
||||
keys_to_delete = []
|
||||
for key, value in my_dict.items():
|
||||
if not ApiError.is_jsonable(value):
|
||||
keys_to_delete.append(key)
|
||||
for key in keys_to_delete:
|
||||
del my_dict[key]
|
||||
return my_dict
|
||||
|
||||
@staticmethod
|
||||
def is_jsonable(x):
|
||||
try:
|
||||
json.dumps(x)
|
||||
return True
|
||||
except (TypeError, OverflowError):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def from_task_spec(cls, code, message, task_spec, status_code=400):
|
||||
"""Constructs an API Error with details pulled from the current task."""
|
||||
@ -89,6 +101,8 @@ class ApiError(Exception):
|
||||
return ApiError.from_task_spec(code, message, exp.sender)
|
||||
|
||||
|
||||
|
||||
|
||||
class ApiErrorSchema(ma.Schema):
|
||||
class Meta:
|
||||
fields = ("code", "message", "workflow_name", "file_name", "task_name", "task_id",
|
||||
|
@ -5,7 +5,6 @@ import inspect
|
||||
import os
|
||||
|
||||
import connexion
|
||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||
from flask import send_file
|
||||
from jinja2 import Template, UndefinedError
|
||||
|
||||
@ -92,7 +91,7 @@ def evaluate_python_expression(body):
|
||||
of the same hash are unnecessary. """
|
||||
try:
|
||||
script_engine = CustomBpmnScriptEngine()
|
||||
result = script_engine.eval(body['expression'], body['data'])
|
||||
result = script_engine._evaluate(body['expression'], **body['data'])
|
||||
return {"result": result, "expression": body['expression'], "key": body['key']}
|
||||
except Exception as e:
|
||||
return {"result": False, "expression": body['expression'], "key": body['key'], "error": str(e)}
|
||||
|
@ -279,7 +279,6 @@ def update_task(workflow_id, task_id, body, terminate_loop=None, update_all=Fals
|
||||
processor = WorkflowProcessor(workflow_model)
|
||||
task_id = uuid.UUID(task_id)
|
||||
spiff_task = processor.bpmn_workflow.get_task(task_id)
|
||||
spiff_task.workflow.script_engine = processor.bpmn_workflow.script_engine
|
||||
_verify_user_and_role(processor, spiff_task)
|
||||
user = UserService.current_user(allow_admin_impersonate=False) # Always log as the real user.
|
||||
|
||||
|
@ -153,7 +153,7 @@ def create_or_update_local_spec(remote,workflow_spec_id):
|
||||
# Set the category
|
||||
if specdict['category'] is not None:
|
||||
local_category = session.query(WorkflowSpecCategoryModel).\
|
||||
filter(WorkflowSpecCategoryModel.name == specdict['category']['name']).first()
|
||||
filter(WorkflowSpecCategoryModel.id == specdict['category']['id']).first()
|
||||
local_category = WorkflowSpecCategoryModelSchema().load(specdict['category'], session=session,
|
||||
instance=local_category)
|
||||
session.add(local_category)
|
||||
|
@ -104,12 +104,11 @@ class StudyEvent(db.Model):
|
||||
|
||||
|
||||
class WorkflowMetadata(object):
|
||||
def __init__(self, id, name = None, display_name = None, description = None, spec_version = None,
|
||||
def __init__(self, id, display_name = None, description = None, spec_version = None,
|
||||
category_id = None, category_display_name = None, state: WorkflowState = None,
|
||||
status: WorkflowStatus = None, total_tasks = None, completed_tasks = None,
|
||||
is_review=None,display_order = None, state_message = None):
|
||||
is_review=None,display_order = None, state_message = None, workflow_spec_id=None):
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.display_name = display_name
|
||||
self.description = description
|
||||
self.spec_version = spec_version
|
||||
@ -122,6 +121,7 @@ class WorkflowMetadata(object):
|
||||
self.completed_tasks = completed_tasks
|
||||
self.is_review = is_review
|
||||
self.display_order = display_order
|
||||
self.workflow_spec_id = workflow_spec_id
|
||||
|
||||
|
||||
@classmethod
|
||||
@ -129,7 +129,6 @@ class WorkflowMetadata(object):
|
||||
is_review = FileService.is_workflow_review(workflow.workflow_spec_id)
|
||||
instance = cls(
|
||||
id=workflow.id,
|
||||
name=workflow.workflow_spec.name,
|
||||
display_name=workflow.workflow_spec.display_name,
|
||||
description=workflow.workflow_spec.description,
|
||||
spec_version=workflow.spec_version(),
|
||||
@ -140,7 +139,8 @@ class WorkflowMetadata(object):
|
||||
total_tasks=workflow.total_tasks,
|
||||
completed_tasks=workflow.completed_tasks,
|
||||
is_review=is_review,
|
||||
display_order=workflow.workflow_spec.display_order
|
||||
display_order=workflow.workflow_spec.display_order,
|
||||
workflow_spec_id=workflow.workflow_spec_id
|
||||
)
|
||||
return instance
|
||||
|
||||
@ -150,7 +150,7 @@ class WorkflowMetadataSchema(ma.Schema):
|
||||
status = EnumField(WorkflowStatus)
|
||||
class Meta:
|
||||
model = WorkflowMetadata
|
||||
additional = ["id", "name", "display_name", "description",
|
||||
additional = ["id", "display_name", "description",
|
||||
"total_tasks", "completed_tasks", "display_order",
|
||||
"category_id", "is_review", "category_display_name", "state_message"]
|
||||
unknown = INCLUDE
|
||||
@ -159,7 +159,6 @@ class WorkflowMetadataSchema(ma.Schema):
|
||||
class Category(object):
|
||||
def __init__(self, model: WorkflowSpecCategoryModel):
|
||||
self.id = model.id
|
||||
self.name = model.name
|
||||
self.display_name = model.display_name
|
||||
self.display_order = model.display_order
|
||||
self.admin = model.admin
|
||||
@ -169,7 +168,7 @@ class CategorySchema(ma.Schema):
|
||||
workflows = fields.List(fields.Nested(WorkflowMetadataSchema), dump_only=True)
|
||||
class Meta:
|
||||
model = Category
|
||||
additional = ["id", "name", "display_name", "display_order", "admin"]
|
||||
additional = ["id", "display_name", "display_order", "admin"]
|
||||
unknown = INCLUDE
|
||||
|
||||
|
||||
|
@ -13,11 +13,11 @@ from crc.models.file import FileModel, FileDataModel
|
||||
class WorkflowSpecCategoryModel(db.Model):
|
||||
__tablename__ = 'workflow_spec_category'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String)
|
||||
display_name = db.Column(db.String)
|
||||
display_order = db.Column(db.Integer)
|
||||
admin = db.Column(db.Boolean)
|
||||
|
||||
|
||||
class WorkflowSpecCategoryModelSchema(SQLAlchemyAutoSchema):
|
||||
class Meta:
|
||||
model = WorkflowSpecCategoryModel
|
||||
@ -25,11 +25,9 @@ class WorkflowSpecCategoryModelSchema(SQLAlchemyAutoSchema):
|
||||
include_relationships = True
|
||||
|
||||
|
||||
|
||||
class WorkflowSpecModel(db.Model):
|
||||
__tablename__ = 'workflow_spec'
|
||||
id = db.Column(db.String, primary_key=True)
|
||||
name = db.Column(db.String)
|
||||
display_name = db.Column(db.String)
|
||||
display_order = db.Column(db.Integer, nullable=True)
|
||||
description = db.Column(db.Text)
|
||||
@ -62,11 +60,9 @@ class WorkflowSpecModelSchema(SQLAlchemyAutoSchema):
|
||||
|
||||
category = marshmallow.fields.Nested(WorkflowSpecCategoryModelSchema, dump_only=True)
|
||||
libraries = marshmallow.fields.Function(lambda obj: [{'id':x.library.id,
|
||||
'name':x.library.name,
|
||||
'display_name':x.library.display_name} for x in
|
||||
obj.libraries] )
|
||||
parents = marshmallow.fields.Function(lambda obj: [{'id':x.parent.id,
|
||||
'name':x.parent.name,
|
||||
'display_name':x.parent.display_name} for x in
|
||||
obj.parents] )
|
||||
|
||||
|
@ -13,13 +13,13 @@ class ResetWorkflow(Script):
|
||||
I.e., a new PI"""
|
||||
|
||||
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
|
||||
return hasattr(kwargs, 'workflow_name')
|
||||
return hasattr(kwargs, 'reset_id')
|
||||
|
||||
def do_task(self, task, study_id, workflow_id, *args, **kwargs):
|
||||
|
||||
if 'workflow_name' in kwargs.keys():
|
||||
workflow_name = kwargs['workflow_name']
|
||||
workflow_spec: WorkflowSpecModel = session.query(WorkflowSpecModel).filter_by(name=workflow_name).first()
|
||||
if 'reset_id' in kwargs.keys():
|
||||
reset_id = kwargs['reset_id']
|
||||
workflow_spec: WorkflowSpecModel = session.query(WorkflowSpecModel).filter_by(id=reset_id).first()
|
||||
if workflow_spec:
|
||||
workflow_model: WorkflowModel = session.query(WorkflowModel).filter_by(
|
||||
workflow_spec_id=workflow_spec.id,
|
||||
@ -35,7 +35,7 @@ class ResetWorkflow(Script):
|
||||
else:
|
||||
raise ApiError(code='missing_workflow_spec',
|
||||
message=f'No WorkflowSpecModel returned. \
|
||||
name: {workflow_name}')
|
||||
id: {workflow_id}')
|
||||
else:
|
||||
raise ApiError(code='missing_workflow_name',
|
||||
message='Reset workflow requires a workflow name')
|
||||
raise ApiError(code='missing_workflow_id',
|
||||
message='Reset workflow requires a workflow id')
|
||||
|
@ -67,10 +67,14 @@ class LookupService(object):
|
||||
# if not, we need to rebuild the lookup table.
|
||||
is_current = False
|
||||
if lookup_model:
|
||||
if lookup_model.is_ldap: # LDAP is always current
|
||||
is_current = True
|
||||
else:
|
||||
is_current = db.session.query(WorkflowSpecDependencyFile). \
|
||||
filter(WorkflowSpecDependencyFile.file_data_id == lookup_model.file_data_model_id).\
|
||||
filter(WorkflowSpecDependencyFile.workflow_id == workflow.id).count()
|
||||
|
||||
|
||||
if not is_current:
|
||||
# Very very very expensive, but we don't know need this till we do.
|
||||
logging.warning("!!!! Making a very expensive call to update the lookup models.")
|
||||
@ -138,6 +142,7 @@ class LookupService(object):
|
||||
# Use the results of an LDAP request to populate enum field options
|
||||
elif field.has_property(Task.FIELD_PROP_LDAP_LOOKUP):
|
||||
lookup_model = LookupFileModel(workflow_spec_id=workflow_model.workflow_spec_id,
|
||||
task_spec_id=task_spec_id,
|
||||
field_id=field_id,
|
||||
is_ldap=True)
|
||||
|
||||
|
@ -433,26 +433,26 @@ class StudyService(object):
|
||||
for wfm in workflow_metas:
|
||||
wfm.state_message = ''
|
||||
# do we have a status for you
|
||||
if wfm.name not in status.keys():
|
||||
warnings.append(ApiError("missing_status", "No status specified for workflow %s" % wfm.name))
|
||||
if wfm.workflow_spec_id not in status.keys():
|
||||
warnings.append(ApiError("missing_status", "No status specified for workflow %s" % wfm.workflow_spec_id))
|
||||
continue
|
||||
if not isinstance(status[wfm.name], dict):
|
||||
if not isinstance(status[wfm.workflow_spec_id], dict):
|
||||
warnings.append(ApiError(code='invalid_status',
|
||||
message=f'Status must be a dictionary with "status" and "message" keys. Name is {wfm.name}. Status is {status[wfm.name]}'))
|
||||
message=f'Status must be a dictionary with "status" and "message" keys. Name is {wfm.workflow_spec_id}. Status is {status[wfm.workflow_spec_id]}'))
|
||||
continue
|
||||
if 'status' not in status[wfm.name].keys():
|
||||
if 'status' not in status[wfm.workflow_spec_id].keys():
|
||||
warnings.append(ApiError("missing_status",
|
||||
"Workflow '%s' does not have a status setting" % wfm.name))
|
||||
"Workflow '%s' does not have a status setting" % wfm.workflow_spec_id))
|
||||
continue
|
||||
if not WorkflowState.has_value(status[wfm.name]['status']):
|
||||
if not WorkflowState.has_value(status[wfm.workflow_spec_id]['status']):
|
||||
warnings.append(ApiError("invalid_state",
|
||||
"Workflow '%s' can not be set to '%s', should be one of %s" % (
|
||||
wfm.name, status[wfm.name]['status'], ",".join(WorkflowState.list())
|
||||
wfm.workflow_spec_id, status[wfm.workflow_spec_id]['status'], ",".join(WorkflowState.list())
|
||||
)))
|
||||
continue
|
||||
wfm.state = WorkflowState[status[wfm.name]['status']]
|
||||
if 'message' in status[wfm.name].keys():
|
||||
wfm.state_message = status[wfm.name]['message']
|
||||
wfm.state = WorkflowState[status[wfm.workflow_spec_id]['status']]
|
||||
if 'message' in status[wfm.workflow_spec_id].keys():
|
||||
wfm.state_message = status[wfm.workflow_spec_id]['message']
|
||||
return warnings
|
||||
|
||||
@staticmethod
|
||||
|
@ -41,7 +41,25 @@ class CustomBpmnScriptEngine(PythonScriptEngine):
|
||||
Evaluate the given expression, within the context of the given task and
|
||||
return the result.
|
||||
"""
|
||||
return self.evaluate_expression(task, expression)
|
||||
study_id = task.workflow.data[WorkflowProcessor.STUDY_ID_KEY]
|
||||
if WorkflowProcessor.WORKFLOW_ID_KEY in task.workflow.data:
|
||||
workflow_id = task.workflow.data[WorkflowProcessor.WORKFLOW_ID_KEY]
|
||||
else:
|
||||
workflow_id = None
|
||||
|
||||
try:
|
||||
if task.workflow.data[WorkflowProcessor.VALIDATION_PROCESS_KEY]:
|
||||
augmentMethods = Script.generate_augmented_validate_list(task, study_id, workflow_id)
|
||||
else:
|
||||
augmentMethods = Script.generate_augmented_list(task, study_id, workflow_id)
|
||||
|
||||
return self._evaluate(expression, external_methods=augmentMethods, **task.data)
|
||||
|
||||
except Exception as e:
|
||||
raise WorkflowTaskExecException(task,
|
||||
"Error evaluating expression "
|
||||
"'%s', %s" % (expression, str(e)))
|
||||
|
||||
|
||||
@timeit
|
||||
def execute(self, task: SpiffTask, script, data):
|
||||
@ -62,32 +80,6 @@ class CustomBpmnScriptEngine(PythonScriptEngine):
|
||||
except Exception as e:
|
||||
raise WorkflowTaskExecException(task, f' {script}, {e}', e)
|
||||
|
||||
def evaluate_expression(self, task, expression):
|
||||
"""
|
||||
Evaluate the given expression, within the context of the given task and
|
||||
return the result.
|
||||
"""
|
||||
study_id = task.workflow.data[WorkflowProcessor.STUDY_ID_KEY]
|
||||
if WorkflowProcessor.WORKFLOW_ID_KEY in task.workflow.data:
|
||||
workflow_id = task.workflow.data[WorkflowProcessor.WORKFLOW_ID_KEY]
|
||||
else:
|
||||
workflow_id = None
|
||||
|
||||
try:
|
||||
if task.workflow.data[WorkflowProcessor.VALIDATION_PROCESS_KEY]:
|
||||
augmentMethods = Script.generate_augmented_validate_list(task, study_id, workflow_id)
|
||||
else:
|
||||
augmentMethods = Script.generate_augmented_list(task, study_id, workflow_id)
|
||||
exp, valid = self.validate_expression(expression)
|
||||
return self._eval(exp, external_methods=augmentMethods, **task.data)
|
||||
|
||||
except Exception as e:
|
||||
raise WorkflowTaskExecException(task,
|
||||
"Error evaluating expression "
|
||||
"'%s', %s" % (expression, str(e)))
|
||||
|
||||
def eval(self, exp, data):
|
||||
return super()._eval(exp, {}, **data)
|
||||
|
||||
|
||||
|
||||
@ -463,9 +455,15 @@ class WorkflowProcessor(object):
|
||||
return nav_item
|
||||
|
||||
def find_spec_and_field(self, spec_name, field_id):
|
||||
"""Tracks down a form field by name in the workflow spec,
|
||||
only looks at ready tasks. Returns a tuple of the task, and form"""
|
||||
for spec in self.bpmn_workflow.spec.task_specs.values():
|
||||
"""Tracks down a form field by name in the workflow spec(s),
|
||||
Returns a tuple of the task, and form"""
|
||||
workflows = [self.bpmn_workflow]
|
||||
for task in self.bpmn_workflow.get_ready_user_tasks():
|
||||
if task.workflow not in workflows:
|
||||
workflows.append(task.workflow)
|
||||
|
||||
for workflow in workflows:
|
||||
for spec in workflow.spec.task_specs.values():
|
||||
if spec.name == spec_name and hasattr(spec, "form"):
|
||||
for field in spec.form.fields:
|
||||
if field.id == field_id:
|
||||
|
@ -1,4 +1,5 @@
|
||||
import copy
|
||||
import json
|
||||
import string
|
||||
from datetime import datetime
|
||||
import random
|
||||
@ -115,7 +116,7 @@ class WorkflowService(object):
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error running waiting task for workflow #%i (%s) for study #%i. %s" %
|
||||
(workflow_model.id,
|
||||
workflow_model.workflow_spec.name,
|
||||
workflow_model.workflow_spec.id,
|
||||
workflow_model.study_id,
|
||||
str(e)))
|
||||
|
||||
@ -137,8 +138,8 @@ class WorkflowService(object):
|
||||
study_model = session.query(StudyModel).filter(StudyModel.id == validate_study_id).first()
|
||||
spec_model = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.id == spec_id).first()
|
||||
status = StudyService._get_study_status(study_model)
|
||||
if spec_model.name in status and status[spec_model.name]['status'] == 'disabled':
|
||||
raise ApiError(code='disabled_workflow', message=f"This workflow is disabled. {status[spec_model.name]['message']}")
|
||||
if spec_model.id in status and status[spec_model.id]['status'] == 'disabled':
|
||||
raise ApiError(code='disabled_workflow', message=f"This workflow is disabled. {status[spec_model.id]['message']}")
|
||||
workflow_model = WorkflowService.make_test_workflow(spec_id, validate_study_id)
|
||||
try:
|
||||
processor = WorkflowProcessor(workflow_model, validate_only=True)
|
||||
@ -149,7 +150,7 @@ class WorkflowService(object):
|
||||
exit_task = processor.bpmn_workflow.do_engine_steps(exit_at=test_until)
|
||||
if (exit_task != None):
|
||||
raise ApiError.from_task("validation_break",
|
||||
f"The validation has been exited early on task '{exit_task.task_spec.name}' and was parented by ",
|
||||
f"The validation has been exited early on task '{exit_task.task_spec.id}' and was parented by ",
|
||||
exit_task.parent)
|
||||
tasks = processor.bpmn_workflow.get_tasks(SpiffTask.READY)
|
||||
for task in tasks:
|
||||
@ -277,7 +278,11 @@ class WorkflowService(object):
|
||||
form_data[field.id] = WorkflowService.get_random_data_for_field(field, task)
|
||||
if task.data is None:
|
||||
task.data = {}
|
||||
task.data.update(form_data)
|
||||
|
||||
# jsonify, and de-jsonify the data to mimic how data will be returned from the front end for forms and assures
|
||||
# we aren't generating something that can't be serialized.
|
||||
form_data_string = json.dumps(form_data)
|
||||
task.data.update(json.loads(form_data_string))
|
||||
|
||||
@staticmethod
|
||||
def check_field_id(id):
|
||||
@ -331,7 +336,7 @@ class WorkflowService(object):
|
||||
# This is generally handled by the front end, but it is possible that the file was uploaded BEFORE
|
||||
# the doc_code was correctly set, so this is a stop gap measure to assure we still hit it correctly.
|
||||
file_id = data[field.id]["id"]
|
||||
doc_code = task.workflow.script_engine.eval(field.get_property(Task.FIELD_PROP_DOC_CODE), data)
|
||||
doc_code = task.workflow.script_engine._evaluate(field.get_property(Task.FIELD_PROP_DOC_CODE), **data)
|
||||
file = db.session.query(FileModel).filter(FileModel.id == file_id).first()
|
||||
if(file):
|
||||
file.irb_doc_code = doc_code
|
||||
@ -369,7 +374,7 @@ class WorkflowService(object):
|
||||
return None # We may not have enough information to process this
|
||||
|
||||
try:
|
||||
return task.workflow.script_engine.eval(expression, data)
|
||||
return task.workflow.script_engine._evaluate(expression, **data)
|
||||
except Exception as e:
|
||||
message = f"The field {field.id} contains an invalid expression. {e}"
|
||||
raise ApiError.from_task(f'invalid_{property_name}', message, task=task)
|
||||
@ -435,6 +440,8 @@ class WorkflowService(object):
|
||||
if default == 'true' or default == 't':
|
||||
return True
|
||||
return False
|
||||
elif field.type == 'date' and isinstance(default, datetime):
|
||||
return default.isoformat()
|
||||
else:
|
||||
return default
|
||||
|
||||
@ -484,8 +491,6 @@ class WorkflowService(object):
|
||||
return [random_value]
|
||||
else:
|
||||
return random_value
|
||||
|
||||
|
||||
elif field.type == "long":
|
||||
return random.randint(1, 1000)
|
||||
elif field.type == 'boolean':
|
||||
@ -690,7 +695,7 @@ class WorkflowService(object):
|
||||
# a BPMN standard, and should not be included in the display.
|
||||
if task.properties and "display_name" in task.properties:
|
||||
try:
|
||||
task.title = spiff_task.workflow.script_engine.evaluate_expression(spiff_task, task.properties[Task.PROP_EXTENSIONS_TITLE])
|
||||
task.title = spiff_task.workflow.script_engine.evaluate(spiff_task, task.properties[Task.PROP_EXTENSIONS_TITLE])
|
||||
except Exception as e:
|
||||
# if the task is ready, we should raise an error, but if it is in the future or the past, we may not
|
||||
# have the information we need to properly set the title, so don't error out, and just use what is
|
||||
|
@ -30,43 +30,36 @@ class ExampleDataLoader:
|
||||
categories = [
|
||||
WorkflowSpecCategoryModel(
|
||||
id=0,
|
||||
name='irb_review',
|
||||
display_name='From PB',
|
||||
display_order=0
|
||||
),
|
||||
WorkflowSpecCategoryModel(
|
||||
id=1,
|
||||
name='core_info',
|
||||
display_name='Core Info',
|
||||
display_order=1
|
||||
),
|
||||
WorkflowSpecCategoryModel(
|
||||
id=2,
|
||||
name='approvals',
|
||||
display_name='Approvals',
|
||||
display_order=2
|
||||
),
|
||||
WorkflowSpecCategoryModel(
|
||||
id=3,
|
||||
name='data_security_plan',
|
||||
display_name='Data Security Plan',
|
||||
display_order=3
|
||||
),
|
||||
WorkflowSpecCategoryModel(
|
||||
id=4,
|
||||
name='finance',
|
||||
display_name='Finance',
|
||||
display_order=4
|
||||
),
|
||||
WorkflowSpecCategoryModel(
|
||||
id=5,
|
||||
name='notifications',
|
||||
display_name='Notifications',
|
||||
display_order=5
|
||||
),
|
||||
WorkflowSpecCategoryModel(
|
||||
id=6,
|
||||
name='status',
|
||||
display_name='Status',
|
||||
display_order=6
|
||||
),
|
||||
@ -77,31 +70,26 @@ class ExampleDataLoader:
|
||||
|
||||
# Pass IRB Review
|
||||
self.create_spec(id="irb_api_personnel",
|
||||
name="irb_api_personnel",
|
||||
display_name="Personnel",
|
||||
description="TBD",
|
||||
category_id=0,
|
||||
display_order=0)
|
||||
self.create_spec(id="irb_api_details",
|
||||
name="irb_api_details",
|
||||
display_name="Protocol Builder Data",
|
||||
description="TBD",
|
||||
category_id=0,
|
||||
display_order=1)
|
||||
self.create_spec(id="documents_approvals",
|
||||
name="documents_approvals",
|
||||
display_name="Documents & Approvals",
|
||||
description="Status of all approvals and documents required from Protocol Builder",
|
||||
category_id=0,
|
||||
display_order=2)
|
||||
self.create_spec(id="ide_supplement",
|
||||
name="ide_supplement",
|
||||
display_name="IDE Supplement Info",
|
||||
description="Supplemental information for the IDE number entered in Protocol Builder",
|
||||
category_id=0,
|
||||
display_order=3)
|
||||
self.create_spec(id="ind_update",
|
||||
name="ind_update",
|
||||
display_name="IND Supplement Info",
|
||||
description="Supplement information for the Investigational New Drug(s) specified in Protocol Builder",
|
||||
category_id=0,
|
||||
@ -109,19 +97,16 @@ class ExampleDataLoader:
|
||||
|
||||
# Core Info
|
||||
self.create_spec(id="protocol",
|
||||
name="protocol",
|
||||
display_name="Protocol",
|
||||
description="Upload the Study Protocol here.",
|
||||
category_id=1,
|
||||
display_order=0)
|
||||
self.create_spec(id="non_uva_approval",
|
||||
name="non_uva",
|
||||
display_name="Non-UVA Institutional Approval",
|
||||
description="TBD",
|
||||
category_id=1,
|
||||
display_order=1)
|
||||
self.create_spec(id="core_info",
|
||||
name="core_info",
|
||||
display_name="Core Info",
|
||||
description="TBD",
|
||||
category_id=1,
|
||||
@ -129,31 +114,26 @@ class ExampleDataLoader:
|
||||
|
||||
# Approvals
|
||||
self.create_spec(id="ids_full_submission",
|
||||
name="ids_full_submission",
|
||||
display_name="Investigational Drug Service (IDS) Full Submission",
|
||||
description="TBD",
|
||||
category_id=2,
|
||||
display_order=0)
|
||||
self.create_spec(id="ids_waiver",
|
||||
name="ids_waiver",
|
||||
display_name="Investigational Drug Service (IDS) Waiver",
|
||||
description="TBD",
|
||||
category_id=2,
|
||||
display_order=1)
|
||||
self.create_spec(id="rsc_hire_submission",
|
||||
name="rsc_hire_submission",
|
||||
display_name="RSC/HIRE Submission",
|
||||
description="TBD",
|
||||
category_id=2,
|
||||
display_order=2)
|
||||
self.create_spec(id="rsc_hire_committee",
|
||||
name="rsc_hire_committee",
|
||||
display_name="RSC/HIRE Committee",
|
||||
description="TBD",
|
||||
category_id=2,
|
||||
display_order=3)
|
||||
self.create_spec(id="department_chair_approval",
|
||||
name="department_chair_approval",
|
||||
display_name="Department Chair Approval",
|
||||
description="TBD",
|
||||
category_id=2,
|
||||
@ -161,7 +141,6 @@ class ExampleDataLoader:
|
||||
|
||||
# Data Security Plan
|
||||
self.create_spec(id="data_security_plan",
|
||||
name="data_security_plan",
|
||||
display_name="Data Security Plan",
|
||||
description="Create and generate Data Security Plan",
|
||||
category_id=3,
|
||||
@ -169,13 +148,11 @@ class ExampleDataLoader:
|
||||
|
||||
# Finance
|
||||
self.create_spec(id="sponsor_funding_source",
|
||||
name="sponsor_funding_source",
|
||||
display_name="Sponsor Funding Source",
|
||||
description="TBD",
|
||||
category_id=4,
|
||||
display_order=0)
|
||||
self.create_spec(id="finance",
|
||||
name="finance",
|
||||
display_name="Finance Data",
|
||||
description="TBD",
|
||||
category_id=4,
|
||||
@ -183,7 +160,6 @@ class ExampleDataLoader:
|
||||
|
||||
# Notifications
|
||||
self.create_spec(id="notifications",
|
||||
name="notifications",
|
||||
display_name="Notifications",
|
||||
description="TBD",
|
||||
category_id=5,
|
||||
@ -191,13 +167,11 @@ class ExampleDataLoader:
|
||||
|
||||
# Status
|
||||
self.create_spec(id="enrollment_date",
|
||||
name="enrollment_date",
|
||||
display_name="Enrollment Date",
|
||||
description="Study enrollment date",
|
||||
category_id=6,
|
||||
display_order=0)
|
||||
self.create_spec(id="abandoned",
|
||||
name="abandoned",
|
||||
display_name="Abandoned",
|
||||
description="Place study into Abandoned status",
|
||||
category_id=6,
|
||||
@ -205,7 +179,6 @@ class ExampleDataLoader:
|
||||
|
||||
# Top Level (Master Status) Workflow
|
||||
self.create_spec(id="top_level_workflow",
|
||||
name="top_level_workflow",
|
||||
display_name="Top Level Workflow",
|
||||
description="Determines the status of other workflows in a study",
|
||||
category_id=None,
|
||||
@ -221,7 +194,6 @@ class ExampleDataLoader:
|
||||
|
||||
category = WorkflowSpecCategoryModel(
|
||||
id=0,
|
||||
name='research_rampup_category',
|
||||
display_name='Research Ramp-up Category',
|
||||
display_order=0
|
||||
)
|
||||
@ -229,14 +201,12 @@ class ExampleDataLoader:
|
||||
db.session.commit()
|
||||
|
||||
self.create_spec(id="rrt_top_level_workflow",
|
||||
name="rrt_top_level_workflow",
|
||||
display_name="Top Level Workflow",
|
||||
description="Does nothing, we don't use the master workflow here.",
|
||||
category_id=None,
|
||||
master_spec=True)
|
||||
|
||||
self.create_spec(id="research_rampup",
|
||||
name="research_rampup",
|
||||
display_name="Research Ramp-up Toolkit",
|
||||
description="Process for creating a new research ramp-up request.",
|
||||
category_id=0,
|
||||
@ -247,7 +217,6 @@ class ExampleDataLoader:
|
||||
|
||||
category = WorkflowSpecCategoryModel(
|
||||
id=0,
|
||||
name='test_category',
|
||||
display_name='Test Category',
|
||||
display_order=0,
|
||||
admin=False
|
||||
@ -256,7 +225,6 @@ class ExampleDataLoader:
|
||||
db.session.commit()
|
||||
|
||||
self.create_spec(id="empty_workflow",
|
||||
name="empty_workflow",
|
||||
display_name="Top Level Workflow",
|
||||
description="Does nothing, we don't use the master workflow here.",
|
||||
category_id=None,
|
||||
@ -264,7 +232,6 @@ class ExampleDataLoader:
|
||||
from_tests = True)
|
||||
|
||||
self.create_spec(id="random_fact",
|
||||
name="random_fact",
|
||||
display_name="Random Fact",
|
||||
description="The workflow for a Random Fact.",
|
||||
category_id=0,
|
||||
@ -272,7 +239,7 @@ class ExampleDataLoader:
|
||||
master_spec=False,
|
||||
from_tests=True)
|
||||
|
||||
def create_spec(self, id, name, display_name="", description="", filepath=None, master_spec=False,
|
||||
def create_spec(self, id, display_name="", description="", filepath=None, master_spec=False,
|
||||
category_id=None, display_order=None, from_tests=False, standalone=False, library=False):
|
||||
"""Assumes that a directory exists in static/bpmn with the same name as the given id.
|
||||
further assumes that the [id].bpmn is the primary file for the workflow.
|
||||
@ -280,7 +247,6 @@ class ExampleDataLoader:
|
||||
global file
|
||||
file_service = FileService()
|
||||
spec = WorkflowSpecModel(id=id,
|
||||
name=name,
|
||||
display_name=display_name,
|
||||
description=description,
|
||||
is_master_spec=master_spec,
|
||||
|
@ -0,0 +1,27 @@
|
||||
"""remove name from spec and category
|
||||
|
||||
Revision ID: 8580676e5302
|
||||
Revises: 5c63a89ee7b7
|
||||
Create Date: 2021-10-04 11:58:41.290139
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '8580676e5302'
|
||||
down_revision = '5c63a89ee7b7'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
|
||||
op.drop_column('workflow_spec_category', 'name')
|
||||
op.drop_column('workflow_spec', 'name')
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.add_column('workflow_spec_category', sa.Column('name', sa.String()))
|
||||
op.add_column('workflow_spec', sa.Column('name', sa.String()))
|
82
migrations/versions/ac1141d29d37_.py
Normal file
82
migrations/versions/ac1141d29d37_.py
Normal file
@ -0,0 +1,82 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: ac1141d29d37
|
||||
Revises: 8580676e5302
|
||||
Create Date: 2021-10-06 14:05:58.062277
|
||||
|
||||
"""
|
||||
import re
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
from crc.models.workflow import WorkflowSpecModel, WorkflowModel
|
||||
|
||||
revision = 'ac1141d29d37'
|
||||
down_revision = '8580676e5302'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
print("Doing the upgrade")
|
||||
op.execute('ALTER TABLE workflow DROP CONSTRAINT workflow_workflow_spec_id_fkey')
|
||||
op.execute('ALTER TABLE file DROP CONSTRAINT file_workflow_spec_id_fkey')
|
||||
op.execute('ALTER TABLE workflow_library DROP CONSTRAINT workflow_library_workflow_spec_id_fkey')
|
||||
op.execute('ALTER TABLE workflow_library DROP CONSTRAINT workflow_library_library_spec_id_fkey')
|
||||
op.execute('ALTER TABLE task_event DROP CONSTRAINT task_event_workflow_spec_id_fkey')
|
||||
# Use Alchemy's connection and transaction to noodle over the data.
|
||||
connection = op.get_bind()
|
||||
|
||||
# Select all existing names that need migrating.
|
||||
results = connection.execute(sa.select([
|
||||
WorkflowSpecModel.id,
|
||||
WorkflowSpecModel.display_name,
|
||||
])).fetchall()
|
||||
# Iterate over all selected data tuples.
|
||||
for id, display_name in results:
|
||||
new_id = display_name.lower().\
|
||||
replace(",", "").\
|
||||
replace("'", "").\
|
||||
replace(" ", "_").\
|
||||
replace("-", "_").\
|
||||
replace(".", "_").\
|
||||
replace("/","_").\
|
||||
replace("\\", "_")
|
||||
old_id = id
|
||||
op.execute("Update workflow_spec set id='%s' where id='%s'" % (new_id, old_id))
|
||||
op.execute("Update workflow set workflow_spec_id='%s' where workflow_spec_id='%s'" % (new_id, old_id))
|
||||
op.execute("Update file set workflow_spec_id='%s' where workflow_spec_id='%s'" % (new_id, old_id))
|
||||
op.execute("Update workflow_library set workflow_spec_id='%s' where workflow_spec_id='%s'" % (new_id, old_id))
|
||||
op.execute("Update workflow_library set library_spec_id='%s' where library_spec_id='%s'" % (new_id, old_id))
|
||||
op.execute("Update task_event set workflow_spec_id='%s' where workflow_spec_id='%s'" % (new_id, old_id))
|
||||
op.create_foreign_key(
|
||||
'workflow_workflow_spec_id_fkey',
|
||||
'workflow', 'workflow_spec',
|
||||
['workflow_spec_id'], ['id'],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
'file_workflow_spec_id_fkey',
|
||||
'file', 'workflow_spec',
|
||||
['workflow_spec_id'], ['id'],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
'workflow_library_workflow_spec_id_fkey',
|
||||
'workflow_library', 'workflow_spec',
|
||||
['workflow_spec_id'], ['id'],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
'workflow_library_library_spec_id_fkey',
|
||||
'workflow_library', 'workflow_spec',
|
||||
['library_spec_id'], ['id'],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
'task_event_workflow_spec_id_fkey',
|
||||
'task_event', 'workflow_spec',
|
||||
['workflow_spec_id'], ['id'],
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
@ -178,7 +178,7 @@ class BaseTest(unittest.TestCase):
|
||||
def load_test_spec(dir_name, display_name=None, master_spec=False, category_id=None):
|
||||
"""Loads a spec into the database based on a directory in /tests/data"""
|
||||
if category_id is None:
|
||||
category = WorkflowSpecCategoryModel(name="test", display_name="Test Workflows", display_order=0)
|
||||
category = WorkflowSpecCategoryModel(display_name="Test Workflows", display_order=0)
|
||||
session.add(category)
|
||||
session.commit()
|
||||
category_id = category.id
|
||||
@ -188,7 +188,7 @@ class BaseTest(unittest.TestCase):
|
||||
filepath = os.path.join(app.root_path, '..', 'tests', 'data', dir_name, "*")
|
||||
if display_name is None:
|
||||
display_name = dir_name
|
||||
return ExampleDataLoader().create_spec(id=dir_name, name=dir_name, filepath=filepath, master_spec=master_spec,
|
||||
return ExampleDataLoader().create_spec(id=dir_name, filepath=filepath, master_spec=master_spec,
|
||||
display_name=display_name, category_id=category_id)
|
||||
|
||||
@staticmethod
|
||||
@ -274,13 +274,13 @@ class BaseTest(unittest.TestCase):
|
||||
return study
|
||||
|
||||
|
||||
def create_workflow(self, workflow_name, display_name=None, study=None, category_id=None, as_user="dhf8r"):
|
||||
def create_workflow(self, dir_name, display_name=None, study=None, category_id=None, as_user="dhf8r"):
|
||||
session.flush()
|
||||
spec = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.name == workflow_name).first()
|
||||
spec = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.id == dir_name).first()
|
||||
if spec is None:
|
||||
if display_name is None:
|
||||
display_name = workflow_name
|
||||
spec = self.load_test_spec(workflow_name, display_name, category_id=category_id)
|
||||
display_name = dir_name
|
||||
spec = self.load_test_spec(dir_name, display_name, category_id=category_id)
|
||||
if study is None:
|
||||
study = self.create_study(uid=as_user)
|
||||
workflow_model = StudyService._create_workflow_model(study, spec)
|
||||
|
65
tests/data/date_value_expression/date_value_expression.bpmn
Normal file
65
tests/data/date_value_expression/date_value_expression.bpmn
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1717350" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.10.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
|
||||
<bpmn:process id="Process_1y3o9tq" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0ecke9e</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0ecke9e" sourceRef="StartEvent_1" targetRef="Date_Value_Expression" />
|
||||
<bpmn:userTask id="Date_Value_Expression" name="Date Form" camunda:formKey="My Form">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="my_date" label="my Date" type="date">
|
||||
<camunda:properties>
|
||||
<camunda:property id="value_expression" value="datetime.datetime.now()" />
|
||||
</camunda:properties>
|
||||
<camunda:validation>
|
||||
<camunda:constraint name="required" config="True" />
|
||||
</camunda:validation>
|
||||
</camunda:formField>
|
||||
</camunda:formData>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_0ecke9e</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_04yzu4r</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
<bpmn:endEvent id="Event_06knzzw">
|
||||
<bpmn:documentation>The Date is {{my_date}}</bpmn:documentation>
|
||||
<bpmn:incoming>Flow_1hz2cs6</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_04yzu4r" sourceRef="Date_Value_Expression" targetRef="Activity_0irsthq" />
|
||||
<bpmn:sequenceFlow id="Flow_1hz2cs6" sourceRef="Activity_0irsthq" targetRef="Event_06knzzw" />
|
||||
<bpmn:scriptTask id="Activity_0irsthq" name="Date Script">
|
||||
<bpmn:incoming>Flow_04yzu4r</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1hz2cs6</bpmn:outgoing>
|
||||
<bpmn:script>dateparser.parse(my_date)
|
||||
</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1y3o9tq">
|
||||
<bpmndi:BPMNEdge id="Flow_0ecke9e_di" bpmnElement="Flow_0ecke9e">
|
||||
<di:waypoint x="215" y="117" />
|
||||
<di:waypoint x="270" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_04yzu4r_di" bpmnElement="Flow_04yzu4r">
|
||||
<di:waypoint x="370" y="117" />
|
||||
<di:waypoint x="420" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1hz2cs6_di" bpmnElement="Flow_1hz2cs6">
|
||||
<di:waypoint x="520" y="117" />
|
||||
<di:waypoint x="542" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0myo4ou_di" bpmnElement="Date_Value_Expression">
|
||||
<dc:Bounds x="270" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_06knzzw_di" bpmnElement="Event_06knzzw">
|
||||
<dc:Bounds x="542" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_01ztf01_di" bpmnElement="Activity_0irsthq">
|
||||
<dc:Bounds x="420" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
@ -29,5 +29,8 @@ class TestEmailScript(BaseTest):
|
||||
self.assertIn(task_data['ApprvlApprvr1'], outbox[0].body)
|
||||
self.assertIn(task_data['ApprvlApprvr1'], outbox[0].html)
|
||||
|
||||
# Correct From field
|
||||
self.assertEqual('uvacrconnect@virginia.edu', outbox[0].sender)
|
||||
|
||||
db_emails = EmailModel.query.count()
|
||||
self.assertEqual(db_emails, 1)
|
||||
|
@ -28,7 +28,7 @@ class TestFilesApi(BaseTest):
|
||||
self.assertEqual(5, len(json_data))
|
||||
files = FileModelSchema(many=True).load(json_data, session=session)
|
||||
file_names = [f.name for f in files]
|
||||
self.assertTrue("%s.bpmn" % spec.name in file_names)
|
||||
self.assertTrue("%s.bpmn" % spec.id in file_names)
|
||||
|
||||
def test_list_multiple_files_for_workflow_spec(self):
|
||||
self.load_example_data()
|
||||
|
@ -67,12 +67,11 @@ class TestStudyApi(BaseTest):
|
||||
# Categories are read only, so switching to sub-scripting here.
|
||||
# This assumes there is one test category set up in the example data.
|
||||
category = study.categories[0]
|
||||
self.assertEqual("test_category", category['name'])
|
||||
self.assertEqual("Test Category", category['display_name'])
|
||||
self.assertEqual(False, category['admin'])
|
||||
self.assertEqual(1, len(category["workflows"]))
|
||||
workflow = category["workflows"][0]
|
||||
self.assertEqual("random_fact", workflow["name"])
|
||||
self.assertEqual("Random Fact", workflow["display_name"])
|
||||
self.assertEqual("optional", workflow["state"])
|
||||
self.assertEqual("not_started", workflow["status"])
|
||||
self.assertEqual(0, workflow["total_tasks"])
|
||||
|
@ -26,7 +26,7 @@ class TestStudyService(BaseTest):
|
||||
|
||||
# Assure some basic models are in place, This is a damn mess. Our database models need an overhaul to make
|
||||
# this easier - better relationship modeling is now critical.
|
||||
cat = WorkflowSpecCategoryModel(name="approvals", display_name="Approvals", display_order=0)
|
||||
cat = WorkflowSpecCategoryModel(id=None, display_name="Approvals", display_order=0)
|
||||
db.session.add(cat)
|
||||
db.session.commit()
|
||||
self.load_test_spec("top_level_workflow", master_spec=True, category_id=cat.id)
|
||||
|
@ -12,7 +12,7 @@ class TestAutoSetPrimaryBPMN(BaseTest):
|
||||
self.load_example_data()
|
||||
category_id = session.query(WorkflowSpecCategoryModel).first().id
|
||||
# Add a workflow spec
|
||||
spec = WorkflowSpecModel(id='make_cookies', name='make_cookies', display_name='Cooooookies',
|
||||
spec = WorkflowSpecModel(id='make_cookies', display_name='Cooooookies',
|
||||
description='Om nom nom delicious cookies', category_id=category_id,
|
||||
standalone=False)
|
||||
rv = self.app.post('/v1.0/workflow-specification',
|
||||
|
@ -102,10 +102,10 @@ class TestTasksApi(BaseTest):
|
||||
# You have a task called "Approval" to be completed in the "Supervisor Approval" workflow
|
||||
# for the study 'Why dogs are stinky' managed by user "Jane Smith (js42x)",
|
||||
# please check here to complete the task.
|
||||
# Display name isn't set in the tests, so just checking name, but the full workflow details are included.
|
||||
# Just checking display_name for workflow, but the full workflow details are included.
|
||||
# I didn't delve into the full user details to keep things decoupled from ldap, so you just get the
|
||||
# uid back, but could query to get the full entry.
|
||||
self.assertEqual("roles", tasks[0]['workflow']['name'])
|
||||
self.assertEqual("Roles", tasks[0]['workflow']['display_name'])
|
||||
self.assertEqual("Beer consumption in the bipedal software engineer", tasks[0]['study']['title'])
|
||||
self.assertEqual("lje5u", tasks[0]['study']['user_uid'])
|
||||
|
||||
|
@ -348,7 +348,7 @@ class TestWorkflowProcessor(BaseTest):
|
||||
|
||||
study = session.query(StudyModel).first()
|
||||
workflow_spec_model = db.session.query(WorkflowSpecModel).\
|
||||
filter(WorkflowSpecModel.name == "top_level_workflow").first()
|
||||
filter(WorkflowSpecModel.id == "top_level_workflow").first()
|
||||
self.assertIsNotNone(workflow_spec_model)
|
||||
|
||||
processor = self.get_processor(study, workflow_spec_model)
|
||||
|
@ -22,7 +22,7 @@ class TestWorkflowReset(BaseTest):
|
||||
second_task = workflow_api.next_task
|
||||
self.assertEqual('Task_GetAge', second_task.name)
|
||||
|
||||
ResetWorkflow().do_task(second_task, workflow.study_id, workflow.id, workflow_name='two_user_tasks')
|
||||
ResetWorkflow().do_task(second_task, workflow.study_id, workflow.id, reset_id='two_user_tasks')
|
||||
|
||||
workflow_api = self.get_workflow_api(workflow)
|
||||
task = workflow_api.next_task
|
||||
@ -42,4 +42,4 @@ class TestWorkflowReset(BaseTest):
|
||||
first_task = workflow_api.next_task
|
||||
|
||||
with self.assertRaises(ApiError):
|
||||
ResetWorkflow().do_task(first_task, workflow.study_id, workflow.id, workflow_name='bad_workflow_name')
|
||||
ResetWorkflow().do_task(first_task, workflow.study_id, workflow.id, reset_id='bad_workflow_name')
|
||||
|
@ -29,7 +29,7 @@ class TestWorkflowSpec(BaseTest):
|
||||
num_before = session.query(WorkflowSpecModel).count()
|
||||
category_id = session.query(WorkflowSpecCategoryModel).first().id
|
||||
category_count = session.query(WorkflowSpecModel).filter_by(category_id=category_id).count()
|
||||
spec = WorkflowSpecModel(id='make_cookies', name='make_cookies', display_name='Cooooookies',
|
||||
spec = WorkflowSpecModel(id='make_cookies', display_name='Cooooookies',
|
||||
description='Om nom nom delicious cookies', category_id=category_id,
|
||||
standalone=False)
|
||||
rv = self.app.post('/v1.0/workflow-specification',
|
||||
@ -58,7 +58,7 @@ class TestWorkflowSpec(BaseTest):
|
||||
self.load_example_data()
|
||||
|
||||
category_id = 99
|
||||
category = WorkflowSpecCategoryModel(id=category_id, name='trap', display_name="It's a trap!", display_order=0)
|
||||
category = WorkflowSpecCategoryModel(id=category_id, display_name="It's a trap!", display_order=0)
|
||||
session.add(category)
|
||||
session.commit()
|
||||
|
||||
@ -107,13 +107,13 @@ class TestWorkflowSpec(BaseTest):
|
||||
def test_display_order_after_delete_spec(self):
|
||||
self.load_example_data()
|
||||
workflow_spec_category = session.query(WorkflowSpecCategoryModel).first()
|
||||
spec_model_1 = WorkflowSpecModel(id='test_spec_1', name='test_spec_1', display_name='Test Spec 1',
|
||||
spec_model_1 = WorkflowSpecModel(id='test_spec_1', display_name='Test Spec 1',
|
||||
description='Test Spec 1 Description', category_id=workflow_spec_category.id,
|
||||
display_order=1, standalone=False)
|
||||
spec_model_2 = WorkflowSpecModel(id='test_spec_2', name='test_spec_2', display_name='Test Spec 2',
|
||||
spec_model_2 = WorkflowSpecModel(id='test_spec_2', display_name='Test Spec 2',
|
||||
description='Test Spec 2 Description', category_id=workflow_spec_category.id,
|
||||
display_order=2, standalone=False)
|
||||
spec_model_3 = WorkflowSpecModel(id='test_spec_3', name='test_spec_3', display_name='Test Spec 3',
|
||||
spec_model_3 = WorkflowSpecModel(id='test_spec_3', display_name='Test Spec 3',
|
||||
description='Test Spec 3 Description', category_id=workflow_spec_category.id,
|
||||
display_order=3, standalone=False)
|
||||
session.add(spec_model_1)
|
||||
@ -159,7 +159,6 @@ class TestWorkflowSpec(BaseTest):
|
||||
count = session.query(WorkflowSpecCategoryModel).count()
|
||||
category = WorkflowSpecCategoryModel(
|
||||
id=count,
|
||||
name='another_test_category',
|
||||
display_name='Another Test Category',
|
||||
display_order=0
|
||||
)
|
||||
@ -169,18 +168,18 @@ class TestWorkflowSpec(BaseTest):
|
||||
data=json.dumps(WorkflowSpecCategoryModelSchema().dump(category))
|
||||
)
|
||||
self.assert_success(rv)
|
||||
result = session.query(WorkflowSpecCategoryModel).filter(WorkflowSpecCategoryModel.name=='another_test_category').first()
|
||||
result = session.query(WorkflowSpecCategoryModel).filter(WorkflowSpecCategoryModel.id==count).first()
|
||||
self.assertEqual('Another Test Category', result.display_name)
|
||||
self.assertEqual(count, result.id)
|
||||
|
||||
def test_update_workflow_spec_category(self):
|
||||
self.load_example_data()
|
||||
category = session.query(WorkflowSpecCategoryModel).first()
|
||||
category_name_before = category.name
|
||||
new_category_name = category_name_before + '_asdf'
|
||||
self.assertNotEqual(category_name_before, new_category_name)
|
||||
display_name_before = category.display_name
|
||||
new_display_name = display_name_before + '_asdf'
|
||||
self.assertNotEqual(display_name_before, new_display_name)
|
||||
|
||||
category.name = new_category_name
|
||||
category.display_name = new_display_name
|
||||
|
||||
rv = self.app.put(f'/v1.0/workflow-specification-category/{category.id}',
|
||||
content_type="application/json",
|
||||
@ -188,25 +187,22 @@ class TestWorkflowSpec(BaseTest):
|
||||
data=json.dumps(WorkflowSpecCategoryModelSchema().dump(category)))
|
||||
self.assert_success(rv)
|
||||
json_data = json.loads(rv.get_data(as_text=True))
|
||||
self.assertEqual(new_category_name, json_data['name'])
|
||||
self.assertEqual(new_display_name, json_data['display_name'])
|
||||
|
||||
def test_delete_workflow_spec_category(self):
|
||||
self.load_example_data()
|
||||
category_model_1 = WorkflowSpecCategoryModel(
|
||||
id=1,
|
||||
name='test_category_1',
|
||||
display_name='Test Category 1',
|
||||
display_order=1
|
||||
)
|
||||
category_model_2 = WorkflowSpecCategoryModel(
|
||||
id=2,
|
||||
name='test_category_2',
|
||||
display_name='Test Category 2',
|
||||
display_order=2
|
||||
)
|
||||
category_model_3 = WorkflowSpecCategoryModel(
|
||||
id=3,
|
||||
name='test_category_3',
|
||||
display_name='Test Category 3',
|
||||
display_order=3
|
||||
)
|
||||
@ -225,7 +221,7 @@ class TestWorkflowSpec(BaseTest):
|
||||
def test_add_library_with_category_id(self):
|
||||
self.load_example_data()
|
||||
category_id = session.query(WorkflowSpecCategoryModel).first().id
|
||||
spec = WorkflowSpecModel(id='test_spec', name='test_spec', display_name='Test Spec',
|
||||
spec = WorkflowSpecModel(id='test_spec', display_name='Test Spec',
|
||||
description='Library with a category id', category_id=category_id,
|
||||
standalone=False, library=True)
|
||||
rv = self.app.post('/v1.0/workflow-specification',
|
||||
|
@ -13,19 +13,16 @@ class TestWorkflowSpecCategoryReorder(BaseTest):
|
||||
def _load_test_categories():
|
||||
category_model_1 = WorkflowSpecCategoryModel(
|
||||
id=1,
|
||||
name='test_category_1',
|
||||
display_name='Test Category 1',
|
||||
display_order=1
|
||||
)
|
||||
category_model_2 = WorkflowSpecCategoryModel(
|
||||
id=2,
|
||||
name='test_category_2',
|
||||
display_name='Test Category 2',
|
||||
display_order=2
|
||||
)
|
||||
category_model_3 = WorkflowSpecCategoryModel(
|
||||
id=3,
|
||||
name='test_category_3',
|
||||
display_name='Test Category 3',
|
||||
display_order=3
|
||||
)
|
||||
|
@ -10,21 +10,21 @@ class TestWorkflowSpecReorder(BaseTest):
|
||||
|
||||
def _load_sample_workflow_specs(self):
|
||||
workflow_spec_category = session.query(WorkflowSpecCategoryModel).first()
|
||||
spec_model_1 = WorkflowSpecModel(id='test_spec_1', name='test_spec_1', display_name='Test Spec 1',
|
||||
spec_model_1 = WorkflowSpecModel(id='test_spec_1', display_name='Test Spec 1',
|
||||
description='Test Spec 1 Description', category_id=workflow_spec_category.id,
|
||||
standalone=False)
|
||||
rv_1 = self.app.post('/v1.0/workflow-specification',
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json",
|
||||
data=json.dumps(WorkflowSpecModelSchema().dump(spec_model_1)))
|
||||
spec_model_2 = WorkflowSpecModel(id='test_spec_2', name='test_spec_2', display_name='Test Spec 2',
|
||||
spec_model_2 = WorkflowSpecModel(id='test_spec_2', display_name='Test Spec 2',
|
||||
description='Test Spec 2 Description', category_id=workflow_spec_category.id,
|
||||
standalone=False)
|
||||
rv_2 = self.app.post('/v1.0/workflow-specification',
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json",
|
||||
data=json.dumps(WorkflowSpecModelSchema().dump(spec_model_2)))
|
||||
spec_model_3 = WorkflowSpecModel(id='test_spec_3', name='test_spec_3', display_name='Test Spec 3',
|
||||
spec_model_3 = WorkflowSpecModel(id='test_spec_3', display_name='Test Spec 3',
|
||||
description='Test Spec 3 Description', category_id=workflow_spec_category.id,
|
||||
standalone=False)
|
||||
rv_3 = self.app.post('/v1.0/workflow-specification',
|
||||
@ -37,11 +37,11 @@ class TestWorkflowSpecReorder(BaseTest):
|
||||
self.load_example_data()
|
||||
rv_1, rv_2, rv_3 = self._load_sample_workflow_specs()
|
||||
self.assertEqual(1, rv_1.json['display_order'])
|
||||
self.assertEqual('test_spec_1', rv_1.json['name'])
|
||||
self.assertEqual('test_spec_1', rv_1.json['id'])
|
||||
self.assertEqual(2, rv_2.json['display_order'])
|
||||
self.assertEqual('test_spec_2', rv_2.json['name'])
|
||||
self.assertEqual('test_spec_2', rv_2.json['id'])
|
||||
self.assertEqual(3, rv_3.json['display_order'])
|
||||
self.assertEqual('test_spec_3', rv_3.json['name'])
|
||||
self.assertEqual('test_spec_3', rv_3.json['id'])
|
||||
|
||||
def test_workflow_spec_reorder_bad_direction(self):
|
||||
self.load_example_data()
|
||||
@ -163,13 +163,13 @@ class TestWorkflowSpecReorder(BaseTest):
|
||||
# but it is
|
||||
# test_spec_1, random_fact, test_spec_2, test_spec_3
|
||||
self.assertEqual(1, bad_orders[0].display_order)
|
||||
self.assertEqual('test_spec_1', bad_orders[0].name)
|
||||
self.assertEqual('test_spec_1', bad_orders[0].id)
|
||||
self.assertEqual(1, bad_orders[1].display_order)
|
||||
self.assertEqual('random_fact', bad_orders[1].name)
|
||||
self.assertEqual('random_fact', bad_orders[1].id)
|
||||
self.assertEqual(1, bad_orders[2].display_order)
|
||||
self.assertEqual('test_spec_2', bad_orders[2].name)
|
||||
self.assertEqual('test_spec_2', bad_orders[2].id)
|
||||
self.assertEqual(3, bad_orders[3].display_order)
|
||||
self.assertEqual('test_spec_3', bad_orders[3].name)
|
||||
self.assertEqual('test_spec_3', bad_orders[3].id)
|
||||
|
||||
# Move test_spec_2 up
|
||||
# This should cause a cleanup of the bad display_order numbers
|
||||
@ -179,11 +179,11 @@ class TestWorkflowSpecReorder(BaseTest):
|
||||
# After moving 2 up, the order should be
|
||||
# test_spec_1, test_spec_2, random_fact, test_spec_3
|
||||
# Make sure we have good display_order numbers too
|
||||
self.assertEqual('test_spec_1', rv.json[0]['name'])
|
||||
self.assertEqual('test_spec_1', rv.json[0]['id'])
|
||||
self.assertEqual(0, rv.json[0]['display_order'])
|
||||
self.assertEqual('test_spec_2', rv.json[1]['name'])
|
||||
self.assertEqual('test_spec_2', rv.json[1]['id'])
|
||||
self.assertEqual(1, rv.json[1]['display_order'])
|
||||
self.assertEqual('random_fact', rv.json[2]['name'])
|
||||
self.assertEqual('random_fact', rv.json[2]['id'])
|
||||
self.assertEqual(2, rv.json[2]['display_order'])
|
||||
self.assertEqual('test_spec_3', rv.json[3]['name'])
|
||||
self.assertEqual('test_spec_3', rv.json[3]['id'])
|
||||
self.assertEqual(3, rv.json[3]['display_order'])
|
||||
|
@ -163,7 +163,6 @@ class TestWorkflowSpecValidation(BaseTest):
|
||||
|
||||
# workflow spec to validate
|
||||
spec_model = WorkflowSpecModel(id='data_security_plan',
|
||||
name='data_security_plan',
|
||||
display_name='Data Security Plan',
|
||||
description='Data Security Plan',
|
||||
is_master_spec=False,
|
||||
@ -186,3 +185,12 @@ class TestWorkflowSpecValidation(BaseTest):
|
||||
api_error = json_data[0]
|
||||
self.assertEqual('disabled_workflow', api_error['code'])
|
||||
self.assertEqual('This workflow is disabled. This is my mocked disable message.', api_error['message'])
|
||||
|
||||
|
||||
def test_date_generation_during_validation(self):
|
||||
# We hit a bug where the date was generated as a part of a value_expression during validation, but
|
||||
# it wasn't converted to an ISO String as it would be if submitted through the API.
|
||||
# subsequent attempts to work with the expected date_string failed, because it was already a date.
|
||||
# This can't happen in the front end code base, but it was breaking validation.
|
||||
errors = self.validate_workflow("date_value_expression")
|
||||
self.assertEqual(0, len(errors))
|
||||
|
Loading…
x
Reference in New Issue
Block a user