diff --git a/coverage/cobertura-coverage.xml b/coverage/cobertura-coverage.xml index 3b63a6a4e..d2f865596 100644 --- a/coverage/cobertura-coverage.xml +++ b/coverage/cobertura-coverage.xml @@ -1,17 +1,17 @@ - + /home/runner/work/snapcraft.io/snapcraft.io - + - + - + - + @@ -29,7 +29,7 @@ - + @@ -2474,9 +2474,9 @@ - + - + @@ -2496,7 +2496,7 @@ - + @@ -2507,10 +2507,10 @@ - + - + @@ -3374,7 +3374,7 @@ - + @@ -3967,81 +3967,81 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5136,400 +5136,138 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - + @@ -5579,36 +5317,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + @@ -5624,7 +5362,7 @@ - + @@ -5632,243 +5370,202 @@ - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - + + + + + + + + + + - + - + - + - + - + - + - + - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + + + + + + + - - - - - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + + + + + + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -5876,136 +5573,180 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + - + - + @@ -6020,21 +5761,21 @@ - - - - + + + + - + - + - + @@ -6057,16 +5798,16 @@ - + - + - - - + + + @@ -6074,15 +5815,15 @@ - - + + - + - + - + @@ -6102,14 +5843,14 @@ - - - - - - - - + + + + + + + + @@ -6123,11 +5864,11 @@ - + - + @@ -6135,78 +5876,53 @@ - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - - - - - - - - - - - - - - + - + - + + + + + + + + + + + + + + + + + + - + @@ -6214,43 +5930,69 @@ - + - + - + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + - + @@ -6258,306 +6000,242 @@ - + - + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + + + + + - - - - - - - + - - - - - - - - - - - + + + + + + + + + + + + - + - + + + + + + + + + + + + - + - + - + - + - + - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + @@ -6598,20 +6276,6 @@ - - - - - - - - - - - - - - @@ -6626,7 +6290,7 @@ - + @@ -7010,16 +6674,16 @@ - + - + - + - + - + @@ -7035,10 +6699,10 @@ - - + + - + @@ -9250,19 +8914,19 @@ - + - + - + - + - - + + @@ -9311,9 +8975,9 @@ - + - + @@ -9321,9 +8985,9 @@ - + - + @@ -9333,12 +8997,12 @@ - - + + - - - + + + @@ -9354,9 +9018,9 @@ - + - + @@ -9376,19 +9040,13 @@ - + - - - - - - @@ -9432,7 +9090,7 @@ - + @@ -9445,85 +9103,85 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - + + + + + - - - @@ -9533,9 +9191,9 @@ - + - + @@ -9553,7 +9211,7 @@ - + @@ -9562,52 +9220,52 @@ - + - + - + - + - + - + - + - + - - - - - - - - - - - - + + + + + + + + + + + + - + - + @@ -9617,206 +9275,206 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - - - - - - + + + + + + + - + - + - - - - - - - + + + + + + + + - + - + - - - - + + + diff --git a/coverage/cobertura-coverage.zip b/coverage/cobertura-coverage.zip index 172aa7a67..1e5a97b0e 100644 Binary files a/coverage/cobertura-coverage.zip and b/coverage/cobertura-coverage.zip differ diff --git a/coverage/coverage.xml b/coverage/coverage.xml index 29646ba6e..6c3b6aa80 100644 --- a/coverage/coverage.xml +++ b/coverage/coverage.xml @@ -1,5 +1,5 @@ - + @@ -1111,13 +1111,13 @@ - + - + @@ -1236,8 +1236,8 @@ - - + + @@ -1247,8 +1247,8 @@ - - + + @@ -1258,8 +1258,8 @@ - - + + @@ -1270,8 +1270,8 @@ - - + + @@ -2545,416 +2545,210 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - - + + + + + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + - - - + + + - - - - - + + + + + + + - + - + + + - + + + + - - - - + + + + + + + + + + - - + - + + + - + - + + + + + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + @@ -2985,148 +2779,33 @@ - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -6136,7 +5815,7 @@ - + @@ -6496,153 +6175,161 @@ - + - - + + - + - - - - - + + + + + - + - - - - + + - - - + + + + + - + + - + + + + + + - - + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - + + + + + + + + + + - + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -6718,38 +6405,38 @@ - - - - + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + @@ -7114,7 +6801,7 @@ - + @@ -7137,206 +6824,205 @@ - - - + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - + + + + + + + + + - - - - + + + - + + - + - - - + - + - + - + - - - - + + + + + + - - + + - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + - + + - - - - - + + + + - + + - - - + + + - + + + - - - - - - - - - + + + + + + - - + + + + + - - - - - - - + + + + + + - - - - - diff --git a/coverage/js/base/ga.ts.html b/coverage/js/base/ga.ts.html index 53008a316..12a5e43d3 100644 --- a/coverage/js/base/ga.ts.html +++ b/coverage/js/base/ga.ts.html @@ -30,9 +30,9 @@

All files / base ga.ts<
- 11.53% + 15.38% Branches - 3/26 + 4/26
@@ -195,7 +195,7 @@

All files / base ga.ts<       -1x +6x 1x     @@ -298,7 +298,7 @@

All files / base ga.ts< to: string, label: string ): void { - Eif (window.dataLayer) { + if (window.dataLayer) { window.dataLayer.push({ event: "GAEvent", eventCategory: `${categoryPrefix}${category}`, @@ -379,7 +379,7 @@

All files / base ga.ts< - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/App/mocks/mockListingData.js.html b/coverage/js/publisher/listing/components/App/mocks/mockListingData.js.html deleted file mode 100644 index 633bd0c18..000000000 --- a/coverage/js/publisher/listing/components/App/mocks/mockListingData.js.html +++ /dev/null @@ -1,6205 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/App/mocks/mockListingData.js - - - - - - - - - -
-
-

All files / publisher/listing/components/App/mocks mockListingData.js

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -1000 -1001 -1002 -1003 -1004 -1005 -1006 -1007 -1008 -1009 -1010 -1011 -1012 -1013 -1014 -1015 -1016 -1017 -1018 -1019 -1020 -1021 -1022 -1023 -1024 -1025 -1026 -1027 -1028 -1029 -1030 -1031 -1032 -1033 -1034 -1035 -1036 -1037 -1038 -1039 -1040 -1041 -1042 -1043 -1044 -1045 -1046 -1047 -1048 -1049 -1050 -1051 -1052 -1053 -1054 -1055 -1056 -1057 -1058 -1059 -1060 -1061 -1062 -1063 -1064 -1065 -1066 -1067 -1068 -1069 -1070 -1071 -1072 -1073 -1074 -1075 -1076 -1077 -1078 -1079 -1080 -1081 -1082 -1083 -1084 -1085 -1086 -1087 -1088 -1089 -1090 -1091 -1092 -1093 -1094 -1095 -1096 -1097 -1098 -1099 -1100 -1101 -1102 -1103 -1104 -1105 -1106 -1107 -1108 -1109 -1110 -1111 -1112 -1113 -1114 -1115 -1116 -1117 -1118 -1119 -1120 -1121 -1122 -1123 -1124 -1125 -1126 -1127 -1128 -1129 -1130 -1131 -1132 -1133 -1134 -1135 -1136 -1137 -1138 -1139 -1140 -1141 -1142 -1143 -1144 -1145 -1146 -1147 -1148 -1149 -1150 -1151 -1152 -1153 -1154 -1155 -1156 -1157 -1158 -1159 -1160 -1161 -1162 -1163 -1164 -1165 -1166 -1167 -1168 -1169 -1170 -1171 -1172 -1173 -1174 -1175 -1176 -1177 -1178 -1179 -1180 -1181 -1182 -1183 -1184 -1185 -1186 -1187 -1188 -1189 -1190 -1191 -1192 -1193 -1194 -1195 -1196 -1197 -1198 -1199 -1200 -1201 -1202 -1203 -1204 -1205 -1206 -1207 -1208 -1209 -1210 -1211 -1212 -1213 -1214 -1215 -1216 -1217 -1218 -1219 -1220 -1221 -1222 -1223 -1224 -1225 -1226 -1227 -1228 -1229 -1230 -1231 -1232 -1233 -1234 -1235 -1236 -1237 -1238 -1239 -1240 -1241 -1242 -1243 -1244 -1245 -1246 -1247 -1248 -1249 -1250 -1251 -1252 -1253 -1254 -1255 -1256 -1257 -1258 -1259 -1260 -1261 -1262 -1263 -1264 -1265 -1266 -1267 -1268 -1269 -1270 -1271 -1272 -1273 -1274 -1275 -1276 -1277 -1278 -1279 -1280 -1281 -1282 -1283 -1284 -1285 -1286 -1287 -1288 -1289 -1290 -1291 -1292 -1293 -1294 -1295 -1296 -1297 -1298 -1299 -1300 -1301 -1302 -1303 -1304 -1305 -1306 -1307 -1308 -1309 -1310 -1311 -1312 -1313 -1314 -1315 -1316 -1317 -1318 -1319 -1320 -1321 -1322 -1323 -1324 -1325 -1326 -1327 -1328 -1329 -1330 -1331 -1332 -1333 -1334 -1335 -1336 -1337 -1338 -1339 -1340 -1341 -1342 -1343 -1344 -1345 -1346 -1347 -1348 -1349 -1350 -1351 -1352 -1353 -1354 -1355 -1356 -1357 -1358 -1359 -1360 -1361 -1362 -1363 -1364 -1365 -1366 -1367 -1368 -1369 -1370 -1371 -1372 -1373 -1374 -1375 -1376 -1377 -1378 -1379 -1380 -1381 -1382 -1383 -1384 -1385 -1386 -1387 -1388 -1389 -1390 -1391 -1392 -1393 -1394 -1395 -1396 -1397 -1398 -1399 -1400 -1401 -1402 -1403 -1404 -1405 -1406 -1407 -1408 -1409 -1410 -1411 -1412 -1413 -1414 -1415 -1416 -1417 -1418 -1419 -1420 -1421 -1422 -1423 -1424 -1425 -1426 -1427 -1428 -1429 -1430 -1431 -1432 -1433 -1434 -1435 -1436 -1437 -1438 -1439 -1440 -1441 -1442 -1443 -1444 -1445 -1446 -1447 -1448 -1449 -1450 -1451 -1452 -1453 -1454 -1455 -1456 -1457 -1458 -1459 -1460 -1461 -1462 -1463 -1464 -1465 -1466 -1467 -1468 -1469 -1470 -1471 -1472 -1473 -1474 -1475 -1476 -1477 -1478 -1479 -1480 -1481 -1482 -1483 -1484 -1485 -1486 -1487 -1488 -1489 -1490 -1491 -1492 -1493 -1494 -1495 -1496 -1497 -1498 -1499 -1500 -1501 -1502 -1503 -1504 -1505 -1506 -1507 -1508 -1509 -1510 -1511 -1512 -1513 -1514 -1515 -1516 -1517 -1518 -1519 -1520 -1521 -1522 -1523 -1524 -1525 -1526 -1527 -1528 -1529 -1530 -1531 -1532 -1533 -1534 -1535 -1536 -1537 -1538 -1539 -1540 -1541 -1542 -1543 -1544 -1545 -1546 -1547 -1548 -1549 -1550 -1551 -1552 -1553 -1554 -1555 -1556 -1557 -1558 -1559 -1560 -1561 -1562 -1563 -1564 -1565 -1566 -1567 -1568 -1569 -1570 -1571 -1572 -1573 -1574 -1575 -1576 -1577 -1578 -1579 -1580 -1581 -1582 -1583 -1584 -1585 -1586 -1587 -1588 -1589 -1590 -1591 -1592 -1593 -1594 -1595 -1596 -1597 -1598 -1599 -1600 -1601 -1602 -1603 -1604 -1605 -1606 -1607 -1608 -1609 -1610 -1611 -1612 -1613 -1614 -1615 -1616 -1617 -1618 -1619 -1620 -1621 -1622 -1623 -1624 -1625 -1626 -1627 -1628 -1629 -1630 -1631 -1632 -1633 -1634 -1635 -1636 -1637 -1638 -1639 -1640 -1641 -1642 -1643 -1644 -1645 -1646 -1647 -1648 -1649 -1650 -1651 -1652 -1653 -1654 -1655 -1656 -1657 -1658 -1659 -1660 -1661 -1662 -1663 -1664 -1665 -1666 -1667 -1668 -1669 -1670 -1671 -1672 -1673 -1674 -1675 -1676 -1677 -1678 -1679 -1680 -1681 -1682 -1683 -1684 -1685 -1686 -1687 -1688 -1689 -1690 -1691 -1692 -1693 -1694 -1695 -1696 -1697 -1698 -1699 -1700 -1701 -1702 -1703 -1704 -1705 -1706 -1707 -1708 -1709 -1710 -1711 -1712 -1713 -1714 -1715 -1716 -1717 -1718 -1719 -1720 -1721 -1722 -1723 -1724 -1725 -1726 -1727 -1728 -1729 -1730 -1731 -1732 -1733 -1734 -1735 -1736 -1737 -1738 -1739 -1740 -1741 -1742 -1743 -1744 -1745 -1746 -1747 -1748 -1749 -1750 -1751 -1752 -1753 -1754 -1755 -1756 -1757 -1758 -1759 -1760 -1761 -1762 -1763 -1764 -1765 -1766 -1767 -1768 -1769 -1770 -1771 -1772 -1773 -1774 -1775 -1776 -1777 -1778 -1779 -1780 -1781 -1782 -1783 -1784 -1785 -1786 -1787 -1788 -1789 -1790 -1791 -1792 -1793 -1794 -1795 -1796 -1797 -1798 -1799 -1800 -1801 -1802 -1803 -1804 -1805 -1806 -1807 -1808 -1809 -1810 -1811 -1812 -1813 -1814 -1815 -1816 -1817 -1818 -1819 -1820 -1821 -1822 -1823 -1824 -1825 -1826 -1827 -1828 -1829 -1830 -1831 -1832 -1833 -1834 -1835 -1836 -1837 -1838 -1839 -1840 -1841 -1842 -1843 -1844 -1845 -1846 -1847 -1848 -1849 -1850 -1851 -1852 -1853 -1854 -1855 -1856 -1857 -1858 -1859 -1860 -1861 -1862 -1863 -1864 -1865 -1866 -1867 -1868 -1869 -1870 -1871 -1872 -1873 -1874 -1875 -1876 -1877 -1878 -1879 -1880 -1881 -1882 -1883 -1884 -1885 -1886 -1887 -1888 -1889 -1890 -1891 -1892 -1893 -1894 -1895 -1896 -1897 -1898 -1899 -1900 -1901 -1902 -1903 -1904 -1905 -1906 -1907 -1908 -1909 -1910 -1911 -1912 -1913 -1914 -1915 -1916 -1917 -1918 -1919 -1920 -1921 -1922 -1923 -1924 -1925 -1926 -1927 -1928 -1929 -1930 -1931 -1932 -1933 -1934 -1935 -1936 -1937 -1938 -1939 -1940 -1941 -1942 -1943 -1944 -1945 -1946 -1947 -1948 -1949 -1950 -1951 -1952 -1953 -1954 -1955 -1956 -1957 -1958 -1959 -1960 -1961 -1962 -1963 -1964 -1965 -1966 -1967 -1968 -1969 -1970 -1971 -1972 -1973 -1974 -1975 -1976 -1977 -1978 -1979 -1980 -1981 -1982 -1983 -1984 -1985 -1986 -1987 -1988 -1989 -1990 -1991 -1992 -1993 -1994 -1995 -1996 -1997 -1998 -1999 -2000 -2001 -2002 -2003 -2004 -2005 -2006 -2007 -2008 -2009 -2010 -2011 -2012 -2013 -2014 -2015 -2016 -2017 -2018 -2019 -2020 -2021 -2022 -2023 -2024 -2025 -2026 -2027 -2028 -2029 -2030 -2031 -2032 -2033 -2034 -2035 -2036 -2037 -2038 -2039 -2040 -2041  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
export default {
-  banner_urls: [
-    "https://dashboard.snapcraft.io/site_media/appmedia/2024/06/banner_YmiU4IP.jpg",
-  ],
-  categories: [
-    {
-      name: "Art and Design",
-      slug: "art-and-design",
-    },
-    {
-      name: "Books and Reference",
-      slug: "books-and-reference",
-    },
-    {
-      name: "Development",
-      slug: "development",
-    },
-    {
-      name: "Devices and IoT",
-      slug: "devices-and-iot",
-    },
-    {
-      name: "Education",
-      slug: "education",
-    },
-    {
-      name: "Entertainment",
-      slug: "entertainment",
-    },
-    {
-      name: "Finance",
-      slug: "finance",
-    },
-    {
-      name: "Games",
-      slug: "games",
-    },
-    {
-      name: "Health and Fitness",
-      slug: "health-and-fitness",
-    },
-    {
-      name: "Music and Audio",
-      slug: "music-and-audio",
-    },
-    {
-      name: "News and Weather",
-      slug: "news-and-weather",
-    },
-    {
-      name: "Personalisation",
-      slug: "personalisation",
-    },
-    {
-      name: "Photo and Video",
-      slug: "photo-and-video",
-    },
-    {
-      name: "Productivity",
-      slug: "productivity",
-    },
-    {
-      name: "Science",
-      slug: "science",
-    },
-    {
-      name: "Security",
-      slug: "security",
-    },
-    {
-      name: "Server and Cloud",
-      slug: "server-and-cloud",
-    },
-    {
-      name: "Social",
-      slug: "social",
-    },
-    {
-      name: "Utilities",
-      slug: "utilities",
-    },
-  ],
-  contact: "mailto:hello@example.com",
-  description: "This is the snap I use for development and testing",
-  from: null,
-  icon_url:
-    "https://dashboard.snapcraft.io/site_media/appmedia/2024/06/icon.jpg_tQ660mJ.png",
-  is_on_stable: "released",
-  license: "AFL-1.1 OR ANTLR-PD-fallback OR Glide",
-  license_type: "simple",
-  licenses: [
-    {
-      key: "Glide",
-      name: "3dfx Glide License",
-    },
-    {
-      key: "AMDPLPA",
-      name: "AMD's plpa_map.c License",
-    },
-    {
-      key: "ANTLR-PD",
-      name: "ANTLR Software Rights Notice",
-    },
-    {
-      key: "ANTLR-PD-fallback",
-      name: "ANTLR Software Rights Notice with license fallback",
-    },
-    {
-      key: "Abstyles",
-      name: "Abstyles License",
-    },
-    {
-      key: "AFL-1.1",
-      name: "Academic Free License v1.1",
-    },
-    {
-      key: "AFL-1.2",
-      name: "Academic Free License v1.2",
-    },
-    {
-      key: "AFL-2.0",
-      name: "Academic Free License v2.0",
-    },
-    {
-      key: "AFL-2.1",
-      name: "Academic Free License v2.1",
-    },
-    {
-      key: "AFL-3.0",
-      name: "Academic Free License v3.0",
-    },
-    {
-      key: "AMPAS",
-      name: "Academy of Motion Picture Arts and Sciences BSD",
-    },
-    {
-      key: "APL-1.0",
-      name: "Adaptive Public License 1.0",
-    },
-    {
-      key: "Adobe-Glyph",
-      name: "Adobe Glyph List License",
-    },
-    {
-      key: "APAFML",
-      name: "Adobe Postscript AFM License",
-    },
-    {
-      key: "Adobe-2006",
-      name: "Adobe Systems Incorporated Source Code License Agreement",
-    },
-    {
-      key: "AGPL-1.0",
-      name: "Affero General Public License v1.0",
-    },
-    {
-      key: "AGPL-1.0-only",
-      name: "Affero General Public License v1.0 only",
-    },
-    {
-      key: "AGPL-1.0-or-later",
-      name: "Affero General Public License v1.0 or later",
-    },
-    {
-      key: "Afmparse",
-      name: "Afmparse License",
-    },
-    {
-      key: "Aladdin",
-      name: "Aladdin Free Public License",
-    },
-    {
-      key: "ADSL",
-      name: "Amazon Digital Services License",
-    },
-    {
-      key: "Apache-1.0",
-      name: "Apache License 1.0",
-    },
-    {
-      key: "Apache-1.1",
-      name: "Apache License 1.1",
-    },
-    {
-      key: "Apache-2.0",
-      name: "Apache License 2.0",
-    },
-    {
-      key: "AML",
-      name: "Apple MIT License",
-    },
-    {
-      key: "APSL-1.0",
-      name: "Apple Public Source License 1.0",
-    },
-    {
-      key: "APSL-1.1",
-      name: "Apple Public Source License 1.1",
-    },
-    {
-      key: "APSL-1.2",
-      name: "Apple Public Source License 1.2",
-    },
-    {
-      key: "APSL-2.0",
-      name: "Apple Public Source License 2.0",
-    },
-    {
-      key: "Artistic-1.0",
-      name: "Artistic License 1.0",
-    },
-    {
-      key: "Artistic-1.0-Perl",
-      name: "Artistic License 1.0 (Perl)",
-    },
-    {
-      key: "Artistic-1.0-cl8",
-      name: "Artistic License 1.0 w/clause 8",
-    },
-    {
-      key: "Artistic-2.0",
-      name: "Artistic License 2.0",
-    },
-    {
-      key: "AAL",
-      name: "Attribution Assurance License",
-    },
-    {
-      key: "BSD-1-Clause",
-      name: "BSD 1-Clause License",
-    },
-    {
-      key: "BSD-2-Clause",
-      name: 'BSD 2-Clause "Simplified" License',
-    },
-    {
-      key: "BSD-2-Clause-FreeBSD",
-      name: "BSD 2-Clause FreeBSD License",
-    },
-    {
-      key: "BSD-2-Clause-NetBSD",
-      name: "BSD 2-Clause NetBSD License",
-    },
-    {
-      key: "BSD-2-Clause-Views",
-      name: "BSD 2-Clause with views sentence",
-    },
-    {
-      key: "BSD-3-Clause",
-      name: 'BSD 3-Clause "New" or "Revised" License',
-    },
-    {
-      key: "BSD-3-Clause-Clear",
-      name: "BSD 3-Clause Clear License",
-    },
-    {
-      key: "BSD-3-Clause-Modification",
-      name: "BSD 3-Clause Modification",
-    },
-    {
-      key: "BSD-3-Clause-No-Nuclear-License",
-      name: "BSD 3-Clause No Nuclear License",
-    },
-    {
-      key: "BSD-3-Clause-No-Nuclear-License-2014",
-      name: "BSD 3-Clause No Nuclear License 2014",
-    },
-    {
-      key: "BSD-3-Clause-No-Nuclear-Warranty",
-      name: "BSD 3-Clause No Nuclear Warranty",
-    },
-    {
-      key: "BSD-3-Clause-Open-MPI",
-      name: "BSD 3-Clause Open MPI variant",
-    },
-    {
-      key: "BSD-4-Clause-Shortened",
-      name: "BSD 4 Clause Shortened",
-    },
-    {
-      key: "BSD-4-Clause",
-      name: 'BSD 4-Clause "Original" or "Old" License',
-    },
-    {
-      key: "BSD-Protection",
-      name: "BSD Protection License",
-    },
-    {
-      key: "BSD-Source-Code",
-      name: "BSD Source Code Attribution",
-    },
-    {
-      key: "0BSD",
-      name: "BSD Zero Clause License",
-    },
-    {
-      key: "BSD-3-Clause-Attribution",
-      name: "BSD with attribution",
-    },
-    {
-      key: "BSD-2-Clause-Patent",
-      name: "BSD-2-Clause Plus Patent License",
-    },
-    {
-      key: "BSD-4-Clause-UC",
-      name: "BSD-4-Clause (University of California-Specific)",
-    },
-    {
-      key: "Bahyph",
-      name: "Bahyph License",
-    },
-    {
-      key: "Barr",
-      name: "Barr License",
-    },
-    {
-      key: "Beerware",
-      name: "Beerware License",
-    },
-    {
-      key: "BitTorrent-1.0",
-      name: "BitTorrent Open Source License v1.0",
-    },
-    {
-      key: "BitTorrent-1.1",
-      name: "BitTorrent Open Source License v1.1",
-    },
-    {
-      key: "BlueOak-1.0.0",
-      name: "Blue Oak Model License 1.0.0",
-    },
-    {
-      key: "BSL-1.0",
-      name: "Boost Software License 1.0",
-    },
-    {
-      key: "Borceux",
-      name: "Borceux license",
-    },
-    {
-      key: "BUSL-1.1",
-      name: "Business Source License 1.1",
-    },
-    {
-      key: "CERN-OHL-P-2.0",
-      name: "CERN Open Hardware Licence Version 2 - Permissive",
-    },
-    {
-      key: "CERN-OHL-S-2.0",
-      name: "CERN Open Hardware Licence Version 2 - Strongly Reciprocal",
-    },
-    {
-      key: "CERN-OHL-W-2.0",
-      name: "CERN Open Hardware Licence Version 2 - Weakly Reciprocal",
-    },
-    {
-      key: "CERN-OHL-1.1",
-      name: "CERN Open Hardware Licence v1.1",
-    },
-    {
-      key: "CERN-OHL-1.2",
-      name: "CERN Open Hardware Licence v1.2",
-    },
-    {
-      key: "MIT-CMU",
-      name: "CMU License",
-    },
-    {
-      key: "CNRI-Jython",
-      name: "CNRI Jython License",
-    },
-    {
-      key: "CNRI-Python",
-      name: "CNRI Python License",
-    },
-    {
-      key: "CNRI-Python-GPL-Compatible",
-      name: "CNRI Python Open Source GPL Compatible License Agreement",
-    },
-    {
-      key: "CUA-OPL-1.0",
-      name: "CUA Office Public License v1.0",
-    },
-    {
-      key: "Caldera",
-      name: "Caldera License",
-    },
-    {
-      key: "CECILL-1.0",
-      name: "CeCILL Free Software License Agreement v1.0",
-    },
-    {
-      key: "CECILL-1.1",
-      name: "CeCILL Free Software License Agreement v1.1",
-    },
-    {
-      key: "CECILL-2.0",
-      name: "CeCILL Free Software License Agreement v2.0",
-    },
-    {
-      key: "CECILL-2.1",
-      name: "CeCILL Free Software License Agreement v2.1",
-    },
-    {
-      key: "CECILL-B",
-      name: "CeCILL-B Free Software License Agreement",
-    },
-    {
-      key: "CECILL-C",
-      name: "CeCILL-C Free Software License Agreement",
-    },
-    {
-      key: "ClArtistic",
-      name: "Clarified Artistic License",
-    },
-    {
-      key: "CPOL-1.02",
-      name: "Code Project Open License 1.02",
-    },
-    {
-      key: "CDDL-1.0",
-      name: "Common Development and Distribution License 1.0",
-    },
-    {
-      key: "CDDL-1.1",
-      name: "Common Development and Distribution License 1.1",
-    },
-    {
-      key: "CPAL-1.0",
-      name: "Common Public Attribution License 1.0",
-    },
-    {
-      key: "CPL-1.0",
-      name: "Common Public License 1.0",
-    },
-    {
-      key: "CDLA-Permissive-1.0",
-      name: "Community Data License Agreement Permissive 1.0",
-    },
-    {
-      key: "CDLA-Sharing-1.0",
-      name: "Community Data License Agreement Sharing 1.0",
-    },
-    {
-      key: "C-UDA-1.0",
-      name: "Computational Use of Data Agreement v1.0",
-    },
-    {
-      key: "CATOSL-1.1",
-      name: "Computer Associates Trusted Open Source License 1.1",
-    },
-    {
-      key: "Condor-1.1",
-      name: "Condor Public License v1.1",
-    },
-    {
-      key: "CC-BY-1.0",
-      name: "Creative Commons Attribution 1.0 Generic",
-    },
-    {
-      key: "CC-BY-2.0",
-      name: "Creative Commons Attribution 2.0 Generic",
-    },
-    {
-      key: "CC-BY-2.5",
-      name: "Creative Commons Attribution 2.5 Generic",
-    },
-    {
-      key: "CC-BY-3.0-AT",
-      name: "Creative Commons Attribution 3.0 Austria",
-    },
-    {
-      key: "CC-BY-3.0-US",
-      name: "Creative Commons Attribution 3.0 United States",
-    },
-    {
-      key: "CC-BY-3.0",
-      name: "Creative Commons Attribution 3.0 Unported",
-    },
-    {
-      key: "CC-BY-4.0",
-      name: "Creative Commons Attribution 4.0 International",
-    },
-    {
-      key: "CC-BY-ND-1.0",
-      name: "Creative Commons Attribution No Derivatives 1.0 Generic",
-    },
-    {
-      key: "CC-BY-ND-2.0",
-      name: "Creative Commons Attribution No Derivatives 2.0 Generic",
-    },
-    {
-      key: "CC-BY-ND-2.5",
-      name: "Creative Commons Attribution No Derivatives 2.5 Generic",
-    },
-    {
-      key: "CC-BY-ND-3.0",
-      name: "Creative Commons Attribution No Derivatives 3.0 Unported",
-    },
-    {
-      key: "CC-BY-ND-4.0",
-      name: "Creative Commons Attribution No Derivatives 4.0 International",
-    },
-    {
-      key: "CC-BY-NC-1.0",
-      name: "Creative Commons Attribution Non Commercial 1.0 Generic",
-    },
-    {
-      key: "CC-BY-NC-2.0",
-      name: "Creative Commons Attribution Non Commercial 2.0 Generic",
-    },
-    {
-      key: "CC-BY-NC-2.5",
-      name: "Creative Commons Attribution Non Commercial 2.5 Generic",
-    },
-    {
-      key: "CC-BY-NC-3.0",
-      name: "Creative Commons Attribution Non Commercial 3.0 Unported",
-    },
-    {
-      key: "CC-BY-NC-4.0",
-      name: "Creative Commons Attribution Non Commercial 4.0 International",
-    },
-    {
-      key: "CC-BY-NC-ND-1.0",
-      name: "Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic",
-    },
-    {
-      key: "CC-BY-NC-ND-2.0",
-      name: "Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic",
-    },
-    {
-      key: "CC-BY-NC-ND-2.5",
-      name: "Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic",
-    },
-    {
-      key: "CC-BY-NC-ND-3.0-IGO",
-      name: "Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO",
-    },
-    {
-      key: "CC-BY-NC-ND-3.0",
-      name: "Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported",
-    },
-    {
-      key: "CC-BY-NC-ND-4.0",
-      name: "Creative Commons Attribution Non Commercial No Derivatives 4.0 International",
-    },
-    {
-      key: "CC-BY-NC-SA-1.0",
-      name: "Creative Commons Attribution Non Commercial Share Alike 1.0 Generic",
-    },
-    {
-      key: "CC-BY-NC-SA-2.0",
-      name: "Creative Commons Attribution Non Commercial Share Alike 2.0 Generic",
-    },
-    {
-      key: "CC-BY-NC-SA-2.5",
-      name: "Creative Commons Attribution Non Commercial Share Alike 2.5 Generic",
-    },
-    {
-      key: "CC-BY-NC-SA-3.0",
-      name: "Creative Commons Attribution Non Commercial Share Alike 3.0 Unported",
-    },
-    {
-      key: "CC-BY-NC-SA-4.0",
-      name: "Creative Commons Attribution Non Commercial Share Alike 4.0 International",
-    },
-    {
-      key: "CC-BY-SA-1.0",
-      name: "Creative Commons Attribution Share Alike 1.0 Generic",
-    },
-    {
-      key: "CC-BY-SA-2.0-UK",
-      name: "Creative Commons Attribution Share Alike 2.0 England and Wales",
-    },
-    {
-      key: "CC-BY-SA-2.0",
-      name: "Creative Commons Attribution Share Alike 2.0 Generic",
-    },
-    {
-      key: "CC-BY-SA-2.1-JP",
-      name: "Creative Commons Attribution Share Alike 2.1 Japan",
-    },
-    {
-      key: "CC-BY-SA-2.5",
-      name: "Creative Commons Attribution Share Alike 2.5 Generic",
-    },
-    {
-      key: "CC-BY-SA-3.0",
-      name: "Creative Commons Attribution Share Alike 3.0 Unported",
-    },
-    {
-      key: "CC-BY-SA-4.0",
-      name: "Creative Commons Attribution Share Alike 4.0 International",
-    },
-    {
-      key: "CC-BY-SA-3.0-AT",
-      name: "Creative Commons Attribution-Share Alike 3.0 Austria",
-    },
-    {
-      key: "CC-PDDC",
-      name: "Creative Commons Public Domain Dedication and Certification",
-    },
-    {
-      key: "CC0-1.0",
-      name: "Creative Commons Zero v1.0 Universal",
-    },
-    {
-      key: "Crossword",
-      name: "Crossword License",
-    },
-    {
-      key: "CAL-1.0",
-      name: "Cryptographic Autonomy License 1.0",
-    },
-    {
-      key: "CAL-1.0-Combined-Work-Exception",
-      name: "Cryptographic Autonomy License 1.0 (Combined Work Exception)",
-    },
-    {
-      key: "CrystalStacker",
-      name: "CrystalStacker License",
-    },
-    {
-      key: "Cube",
-      name: "Cube License",
-    },
-    {
-      key: "DOC",
-      name: "DOC License",
-    },
-    {
-      key: "DSDP",
-      name: "DSDP License",
-    },
-    {
-      key: "DRL-1.0",
-      name: "Detection Rule License 1.0",
-    },
-    {
-      key: "D-FSL-1.0",
-      name: "Deutsche Freie Software Lizenz",
-    },
-    {
-      key: "WTFPL",
-      name: "Do What The F*ck You Want To Public License",
-    },
-    {
-      key: "Dotseqn",
-      name: "Dotseqn License",
-    },
-    {
-      key: "EPICS",
-      name: "EPICS Open License",
-    },
-    {
-      key: "EUDatagrid",
-      name: "EU DataGrid Software License",
-    },
-    {
-      key: "EPL-1.0",
-      name: "Eclipse Public License 1.0",
-    },
-    {
-      key: "EPL-2.0",
-      name: "Eclipse Public License 2.0",
-    },
-    {
-      key: "ECL-1.0",
-      name: "Educational Community License v1.0",
-    },
-    {
-      key: "ECL-2.0",
-      name: "Educational Community License v2.0",
-    },
-    {
-      key: "EFL-1.0",
-      name: "Eiffel Forum License v1.0",
-    },
-    {
-      key: "EFL-2.0",
-      name: "Eiffel Forum License v2.0",
-    },
-    {
-      key: "MIT-advertising",
-      name: "Enlightenment License (e16)",
-    },
-    {
-      key: "Entessa",
-      name: "Entessa Public License v1.0",
-    },
-    {
-      key: "ErlPL-1.1",
-      name: "Erlang Public License v1.1",
-    },
-    {
-      key: "etalab-2.0",
-      name: "Etalab Open License 2.0",
-    },
-    {
-      key: "EUPL-1.0",
-      name: "European Union Public License 1.0",
-    },
-    {
-      key: "EUPL-1.1",
-      name: "European Union Public License 1.1",
-    },
-    {
-      key: "EUPL-1.2",
-      name: "European Union Public License 1.2",
-    },
-    {
-      key: "Eurosym",
-      name: "Eurosym License",
-    },
-    {
-      key: "FSFAP",
-      name: "FSF All Permissive License",
-    },
-    {
-      key: "FSFUL",
-      name: "FSF Unlimited License",
-    },
-    {
-      key: "FSFULLR",
-      name: "FSF Unlimited License (with License Retention)",
-    },
-    {
-      key: "Fair",
-      name: "Fair License",
-    },
-    {
-      key: "Frameworx-1.0",
-      name: "Frameworx Open License 1.0",
-    },
-    {
-      key: "FreeBSD-DOC",
-      name: "FreeBSD Documentation License",
-    },
-    {
-      key: "FreeImage",
-      name: "FreeImage Public License v1.0",
-    },
-    {
-      key: "FTL",
-      name: "Freetype Project License",
-    },
-    {
-      key: "GD",
-      name: "GD License",
-    },
-    {
-      key: "GL2PS",
-      name: "GL2PS License",
-    },
-    {
-      key: "AGPL-3.0",
-      name: "GNU Affero General Public License v3.0",
-    },
-    {
-      key: "AGPL-3.0-only",
-      name: "GNU Affero General Public License v3.0 only",
-    },
-    {
-      key: "AGPL-3.0-or-later",
-      name: "GNU Affero General Public License v3.0 or later",
-    },
-    {
-      key: "AGPL-3.0+",
-      name: "GNU Affero General Public License v3.0 or later",
-    },
-    {
-      key: "GFDL-1.1",
-      name: "GNU Free Documentation License v1.1",
-    },
-    {
-      key: "GFDL-1.1-only",
-      name: "GNU Free Documentation License v1.1 only",
-    },
-    {
-      key: "GFDL-1.1-invariants-only",
-      name: "GNU Free Documentation License v1.1 only - invariants",
-    },
-    {
-      key: "GFDL-1.1-no-invariants-only",
-      name: "GNU Free Documentation License v1.1 only - no invariants",
-    },
-    {
-      key: "GFDL-1.1-or-later",
-      name: "GNU Free Documentation License v1.1 or later",
-    },
-    {
-      key: "GFDL-1.1-invariants-or-later",
-      name: "GNU Free Documentation License v1.1 or later - invariants",
-    },
-    {
-      key: "GFDL-1.1-no-invariants-or-later",
-      name: "GNU Free Documentation License v1.1 or later - no invariants",
-    },
-    {
-      key: "GFDL-1.2",
-      name: "GNU Free Documentation License v1.2",
-    },
-    {
-      key: "GFDL-1.2-only",
-      name: "GNU Free Documentation License v1.2 only",
-    },
-    {
-      key: "GFDL-1.2-invariants-only",
-      name: "GNU Free Documentation License v1.2 only - invariants",
-    },
-    {
-      key: "GFDL-1.2-no-invariants-only",
-      name: "GNU Free Documentation License v1.2 only - no invariants",
-    },
-    {
-      key: "GFDL-1.2-or-later",
-      name: "GNU Free Documentation License v1.2 or later",
-    },
-    {
-      key: "GFDL-1.2-invariants-or-later",
-      name: "GNU Free Documentation License v1.2 or later - invariants",
-    },
-    {
-      key: "GFDL-1.2-no-invariants-or-later",
-      name: "GNU Free Documentation License v1.2 or later - no invariants",
-    },
-    {
-      key: "GFDL-1.3",
-      name: "GNU Free Documentation License v1.3",
-    },
-    {
-      key: "GFDL-1.3-only",
-      name: "GNU Free Documentation License v1.3 only",
-    },
-    {
-      key: "GFDL-1.3-invariants-only",
-      name: "GNU Free Documentation License v1.3 only - invariants",
-    },
-    {
-      key: "GFDL-1.3-no-invariants-only",
-      name: "GNU Free Documentation License v1.3 only - no invariants",
-    },
-    {
-      key: "GFDL-1.3-or-later",
-      name: "GNU Free Documentation License v1.3 or later",
-    },
-    {
-      key: "GFDL-1.3-invariants-or-later",
-      name: "GNU Free Documentation License v1.3 or later - invariants",
-    },
-    {
-      key: "GFDL-1.3-no-invariants-or-later",
-      name: "GNU Free Documentation License v1.3 or later - no invariants",
-    },
-    {
-      key: "GPL-1.0-only",
-      name: "GNU General Public License v1.0 only",
-    },
-    {
-      key: "GPL-1.0",
-      name: "GNU General Public License v1.0 only",
-    },
-    {
-      key: "GPL-1.0-or-later",
-      name: "GNU General Public License v1.0 or later",
-    },
-    {
-      key: "GPL-1.0+",
-      name: "GNU General Public License v1.0 or later",
-    },
-    {
-      key: "GPL-2.0-only",
-      name: "GNU General Public License v2.0 only",
-    },
-    {
-      key: "GPL-2.0",
-      name: "GNU General Public License v2.0 only",
-    },
-    {
-      key: "GPL-2.0-or-later",
-      name: "GNU General Public License v2.0 or later",
-    },
-    {
-      key: "GPL-2.0+",
-      name: "GNU General Public License v2.0 or later",
-    },
-    {
-      key: "GPL-2.0-with-autoconf-exception",
-      name: "GNU General Public License v2.0 w/Autoconf exception",
-    },
-    {
-      key: "GPL-2.0-with-bison-exception",
-      name: "GNU General Public License v2.0 w/Bison exception",
-    },
-    {
-      key: "GPL-2.0-with-classpath-exception",
-      name: "GNU General Public License v2.0 w/Classpath exception",
-    },
-    {
-      key: "GPL-2.0-with-font-exception",
-      name: "GNU General Public License v2.0 w/Font exception",
-    },
-    {
-      key: "GPL-2.0-with-GCC-exception",
-      name: "GNU General Public License v2.0 w/GCC Runtime Library exception",
-    },
-    {
-      key: "GPL-3.0",
-      name: "GNU General Public License v3.0 only",
-    },
-    {
-      key: "GPL-3.0-only",
-      name: "GNU General Public License v3.0 only",
-    },
-    {
-      key: "GPL-3.0+",
-      name: "GNU General Public License v3.0 or later",
-    },
-    {
-      key: "GPL-3.0-or-later",
-      name: "GNU General Public License v3.0 or later",
-    },
-    {
-      key: "GPL-3.0-with-autoconf-exception",
-      name: "GNU General Public License v3.0 w/Autoconf exception",
-    },
-    {
-      key: "GPL-3.0-with-GCC-exception",
-      name: "GNU General Public License v3.0 w/GCC Runtime Library exception",
-    },
-    {
-      key: "LGPL-2.1-only",
-      name: "GNU Lesser General Public License v2.1 only",
-    },
-    {
-      key: "LGPL-2.1",
-      name: "GNU Lesser General Public License v2.1 only",
-    },
-    {
-      key: "LGPL-2.1-or-later",
-      name: "GNU Lesser General Public License v2.1 or later",
-    },
-    {
-      key: "LGPL-3.0-only",
-      name: "GNU Lesser General Public License v3.0 only",
-    },
-    {
-      key: "LGPL-3.0",
-      name: "GNU Lesser General Public License v3.0 only",
-    },
-    {
-      key: "LGPL-3.0-or-later",
-      name: "GNU Lesser General Public License v3.0 or later",
-    },
-    {
-      key: "LGPL-3.0+",
-      name: "GNU Lesser General Public License v3.0 or later",
-    },
-    {
-      key: "LGPL-2.0-only",
-      name: "GNU Library General Public License v2 only",
-    },
-    {
-      key: "LGPL-2.0",
-      name: "GNU Library General Public License v2 only",
-    },
-    {
-      key: "LGPL-2.0-or-later",
-      name: "GNU Library General Public License v2 or later",
-    },
-    {
-      key: "LGPL-2.0+",
-      name: "GNU Library General Public License v2 or later",
-    },
-    {
-      key: "LGPL-2.1+",
-      name: "GNU Library General Public License v2.1 or later",
-    },
-    {
-      key: "Giftware",
-      name: "Giftware License",
-    },
-    {
-      key: "Glulxe",
-      name: "Glulxe License",
-    },
-    {
-      key: "GLWTPL",
-      name: "Good Luck With That Public License",
-    },
-    {
-      key: "HTMLTIDY",
-      name: "HTML Tidy License",
-    },
-    {
-      key: "HaskellReport",
-      name: "Haskell Language Report License",
-    },
-    {
-      key: "Hippocratic-2.1",
-      name: "Hippocratic License 2.1",
-    },
-    {
-      key: "HPND",
-      name: "Historical Permission Notice and Disclaimer",
-    },
-    {
-      key: "HPND-sell-variant",
-      name: "Historical Permission Notice and Disclaimer - sell variant",
-    },
-    {
-      key: "IBM-pibs",
-      name: "IBM PowerPC Initialization and Boot Software",
-    },
-    {
-      key: "IPL-1.0",
-      name: "IBM Public License v1.0",
-    },
-    {
-      key: "ICU",
-      name: "ICU License",
-    },
-    {
-      key: "IPA",
-      name: "IPA Font License",
-    },
-    {
-      key: "ISC",
-      name: "ISC License",
-    },
-    {
-      key: "ImageMagick",
-      name: "ImageMagick License",
-    },
-    {
-      key: "Imlib2",
-      name: "Imlib2 License",
-    },
-    {
-      key: "IJG",
-      name: "Independent JPEG Group License",
-    },
-    {
-      key: "Info-ZIP",
-      name: "Info-ZIP License",
-    },
-    {
-      key: "Intel-ACPI",
-      name: "Intel ACPI Software License Agreement",
-    },
-    {
-      key: "Intel",
-      name: "Intel Open Source License",
-    },
-    {
-      key: "Interbase-1.0",
-      name: "Interbase Public License v1.0",
-    },
-    {
-      key: "JSON",
-      name: "JSON License",
-    },
-    {
-      key: "JPNIC",
-      name: "Japan Network Information Center License",
-    },
-    {
-      key: "JasPer-2.0",
-      name: "JasPer License",
-    },
-    {
-      key: "LPPL-1.0",
-      name: "LaTeX Project Public License v1.0",
-    },
-    {
-      key: "LPPL-1.1",
-      name: "LaTeX Project Public License v1.1",
-    },
-    {
-      key: "LPPL-1.2",
-      name: "LaTeX Project Public License v1.2",
-    },
-    {
-      key: "LPPL-1.3a",
-      name: "LaTeX Project Public License v1.3a",
-    },
-    {
-      key: "LPPL-1.3c",
-      name: "LaTeX Project Public License v1.3c",
-    },
-    {
-      key: "Latex2e",
-      name: "Latex2e License",
-    },
-    {
-      key: "BSD-3-Clause-LBNL",
-      name: "Lawrence Berkeley National Labs BSD variant license",
-    },
-    {
-      key: "Leptonica",
-      name: "Leptonica License",
-    },
-    {
-      key: "LGPLLR",
-      name: "Lesser General Public License For Linguistic Resources",
-    },
-    {
-      key: "LAL-1.2",
-      name: "Licence Art Libre 1.2",
-    },
-    {
-      key: "LAL-1.3",
-      name: "Licence Art Libre 1.3",
-    },
-    {
-      key: "LiLiQ-P-1.1",
-      name: "Licence Libre du Québec – Permissive version 1.1",
-    },
-    {
-      key: "LiLiQ-Rplus-1.1",
-      name: "Licence Libre du Québec – Réciprocité forte version 1.1",
-    },
-    {
-      key: "LiLiQ-R-1.1",
-      name: "Licence Libre du Québec – Réciprocité version 1.1",
-    },
-    {
-      key: "Linux-OpenIB",
-      name: "Linux Kernel Variant of OpenIB.org license",
-    },
-    {
-      key: "LPL-1.0",
-      name: "Lucent Public License Version 1.0",
-    },
-    {
-      key: "LPL-1.02",
-      name: "Lucent Public License v1.02",
-    },
-    {
-      key: "MITNFA",
-      name: "MIT +no-false-attribs license",
-    },
-    {
-      key: "MIT",
-      name: "MIT License",
-    },
-    {
-      key: "MIT-Modern-Variant",
-      name: "MIT License Modern Variant",
-    },
-    {
-      key: "MIT-0",
-      name: "MIT No Attribution",
-    },
-    {
-      key: "MIT-open-group",
-      name: "MIT Open Group variant",
-    },
-    {
-      key: "MakeIndex",
-      name: "MakeIndex License",
-    },
-    {
-      key: "MTLL",
-      name: "Matrix Template Library License",
-    },
-    {
-      key: "MS-PL",
-      name: "Microsoft Public License",
-    },
-    {
-      key: "MS-RL",
-      name: "Microsoft Reciprocal License",
-    },
-    {
-      key: "Motosoto",
-      name: "Motosoto License",
-    },
-    {
-      key: "MPL-1.0",
-      name: "Mozilla Public License 1.0",
-    },
-    {
-      key: "MPL-1.1",
-      name: "Mozilla Public License 1.1",
-    },
-    {
-      key: "MPL-2.0",
-      name: "Mozilla Public License 2.0",
-    },
-    {
-      key: "MPL-2.0-no-copyleft-exception",
-      name: "Mozilla Public License 2.0 (no copyleft exception)",
-    },
-    {
-      key: "MulanPSL-1.0",
-      name: "Mulan Permissive Software License, Version 1",
-    },
-    {
-      key: "MulanPSL-2.0",
-      name: "Mulan Permissive Software License, Version 2",
-    },
-    {
-      key: "Multics",
-      name: "Multics License",
-    },
-    {
-      key: "Mup",
-      name: "Mup License",
-    },
-    {
-      key: "NASA-1.3",
-      name: "NASA Open Source Agreement 1.3",
-    },
-    {
-      key: "NIST-PD",
-      name: "NIST Public Domain Notice",
-    },
-    {
-      key: "NIST-PD-fallback",
-      name: "NIST Public Domain Notice with license fallback",
-    },
-    {
-      key: "NRL",
-      name: "NRL License",
-    },
-    {
-      key: "NTP",
-      name: "NTP License",
-    },
-    {
-      key: "NTP-0",
-      name: "NTP No Attribution",
-    },
-    {
-      key: "NAIST-2003",
-      name: "Nara Institute of Science and Technology License (2003)",
-    },
-    {
-      key: "Naumen",
-      name: "Naumen Public License",
-    },
-    {
-      key: "NBPL-1.0",
-      name: "Net Boolean Public License v1",
-    },
-    {
-      key: "Net-SNMP",
-      name: "Net-SNMP License",
-    },
-    {
-      key: "NetCDF",
-      name: "NetCDF license",
-    },
-    {
-      key: "NGPL",
-      name: "Nethack General Public License",
-    },
-    {
-      key: "NOSL",
-      name: "Netizen Open Source License",
-    },
-    {
-      key: "NPL-1.0",
-      name: "Netscape Public License v1.0",
-    },
-    {
-      key: "NPL-1.1",
-      name: "Netscape Public License v1.1",
-    },
-    {
-      key: "Newsletr",
-      name: "Newsletr License",
-    },
-    {
-      key: "NLPL",
-      name: "No Limit Public License",
-    },
-    {
-      key: "Nokia",
-      name: "Nokia Open Source License",
-    },
-    {
-      key: "NCGL-UK-2.0",
-      name: "Non-Commercial Government Licence",
-    },
-    {
-      key: "NPOSL-3.0",
-      name: "Non-Profit Open Software License 3.0",
-    },
-    {
-      key: "NLOD-1.0",
-      name: "Norwegian Licence for Open Government Data",
-    },
-    {
-      key: "Noweb",
-      name: "Noweb License",
-    },
-    {
-      key: "Nunit",
-      name: "Nunit License",
-    },
-    {
-      key: "OCLC-2.0",
-      name: "OCLC Research Public License 2.0",
-    },
-    {
-      key: "OGC-1.0",
-      name: "OGC Software License, Version 1.0",
-    },
-    {
-      key: "OSET-PL-2.1",
-      name: "OSET Public License version 2.1",
-    },
-    {
-      key: "OCCT-PL",
-      name: "Open CASCADE Technology Public License",
-    },
-    {
-      key: "ODC-By-1.0",
-      name: "Open Data Commons Attribution License v1.0",
-    },
-    {
-      key: "ODbL-1.0",
-      name: "Open Data Commons Open Database License v1.0",
-    },
-    {
-      key: "PDDL-1.0",
-      name: "Open Data Commons Public Domain Dedication & License 1.0",
-    },
-    {
-      key: "OGL-Canada-2.0",
-      name: "Open Government Licence - Canada",
-    },
-    {
-      key: "OGL-UK-1.0",
-      name: "Open Government Licence v1.0",
-    },
-    {
-      key: "OGL-UK-2.0",
-      name: "Open Government Licence v2.0",
-    },
-    {
-      key: "OGL-UK-3.0",
-      name: "Open Government Licence v3.0",
-    },
-    {
-      key: "OGTSL",
-      name: "Open Group Test Suite License",
-    },
-    {
-      key: "OLDAP-2.2.2",
-      name: "Open LDAP Public License 2.2.2",
-    },
-    {
-      key: "OLDAP-1.1",
-      name: "Open LDAP Public License v1.1",
-    },
-    {
-      key: "OLDAP-1.2",
-      name: "Open LDAP Public License v1.2",
-    },
-    {
-      key: "OLDAP-1.3",
-      name: "Open LDAP Public License v1.3",
-    },
-    {
-      key: "OLDAP-1.4",
-      name: "Open LDAP Public License v1.4",
-    },
-    {
-      key: "OLDAP-2.0",
-      name: "Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B)",
-    },
-    {
-      key: "OLDAP-2.0.1",
-      name: "Open LDAP Public License v2.0.1",
-    },
-    {
-      key: "OLDAP-2.1",
-      name: "Open LDAP Public License v2.1",
-    },
-    {
-      key: "OLDAP-2.2",
-      name: "Open LDAP Public License v2.2",
-    },
-    {
-      key: "OLDAP-2.2.1",
-      name: "Open LDAP Public License v2.2.1",
-    },
-    {
-      key: "OLDAP-2.3",
-      name: "Open LDAP Public License v2.3",
-    },
-    {
-      key: "OLDAP-2.4",
-      name: "Open LDAP Public License v2.4",
-    },
-    {
-      key: "OLDAP-2.5",
-      name: "Open LDAP Public License v2.5",
-    },
-    {
-      key: "OLDAP-2.6",
-      name: "Open LDAP Public License v2.6",
-    },
-    {
-      key: "OLDAP-2.7",
-      name: "Open LDAP Public License v2.7",
-    },
-    {
-      key: "OLDAP-2.8",
-      name: "Open LDAP Public License v2.8",
-    },
-    {
-      key: "OML",
-      name: "Open Market License",
-    },
-    {
-      key: "OPL-1.0",
-      name: "Open Public License v1.0",
-    },
-    {
-      key: "OSL-1.0",
-      name: "Open Software License 1.0",
-    },
-    {
-      key: "OSL-1.1",
-      name: "Open Software License 1.1",
-    },
-    {
-      key: "OSL-2.0",
-      name: "Open Software License 2.0",
-    },
-    {
-      key: "OSL-2.1",
-      name: "Open Software License 2.1",
-    },
-    {
-      key: "OSL-3.0",
-      name: "Open Software License 3.0",
-    },
-    {
-      key: "O-UDA-1.0",
-      name: "Open Use of Data Agreement v1.0",
-    },
-    {
-      key: "OpenSSL",
-      name: "OpenSSL License",
-    },
-    {
-      key: "Other Open Source",
-      name: "Other Open Source",
-    },
-    {
-      key: "PHP-3.0",
-      name: "PHP License v3.0",
-    },
-    {
-      key: "PHP-3.01",
-      name: "PHP License v3.01",
-    },
-    {
-      key: "libpng-2.0",
-      name: "PNG Reference Library version 2",
-    },
-    {
-      key: "Plexus",
-      name: "Plexus Classworlds License",
-    },
-    {
-      key: "PolyForm-Noncommercial-1.0.0",
-      name: "PolyForm Noncommercial License 1.0.0",
-    },
-    {
-      key: "PolyForm-Small-Business-1.0.0",
-      name: "PolyForm Small Business License 1.0.0",
-    },
-    {
-      key: "PostgreSQL",
-      name: "PostgreSQL License",
-    },
-    {
-      key: "Proprietary",
-      name: "Proprietary",
-    },
-    {
-      key: "Python-2.0",
-      name: "Python License 2.0",
-    },
-    {
-      key: "PSF-2.0",
-      name: "Python Software Foundation License 2.0",
-    },
-    {
-      key: "QPL-1.0",
-      name: "Q Public License 1.0",
-    },
-    {
-      key: "Qhull",
-      name: "Qhull License",
-    },
-    {
-      key: "RSA-MD",
-      name: "RSA Message-Digest License",
-    },
-    {
-      key: "Rdisc",
-      name: "Rdisc License",
-    },
-    {
-      key: "RPSL-1.0",
-      name: "RealNetworks Public Source License v1.0",
-    },
-    {
-      key: "RPL-1.1",
-      name: "Reciprocal Public License 1.1",
-    },
-    {
-      key: "RPL-1.5",
-      name: "Reciprocal Public License 1.5",
-    },
-    {
-      key: "RHeCos-1.1",
-      name: "Red Hat eCos Public License v1.1",
-    },
-    {
-      key: "RSCPL",
-      name: "Ricoh Source Code Public License",
-    },
-    {
-      key: "Ruby",
-      name: "Ruby License",
-    },
-    {
-      key: "SCEA",
-      name: "SCEA Shared Source License",
-    },
-    {
-      key: "SGI-B-1.0",
-      name: "SGI Free Software License B v1.0",
-    },
-    {
-      key: "SGI-B-1.1",
-      name: "SGI Free Software License B v1.1",
-    },
-    {
-      key: "SGI-B-2.0",
-      name: "SGI Free Software License B v2.0",
-    },
-    {
-      key: "OFL-1.0",
-      name: "SIL Open Font License 1.0",
-    },
-    {
-      key: "OFL-1.0-RFN",
-      name: "SIL Open Font License 1.0 with Reserved Font Name",
-    },
-    {
-      key: "OFL-1.0-no-RFN",
-      name: "SIL Open Font License 1.0 with no Reserved Font Name",
-    },
-    {
-      key: "OFL-1.1",
-      name: "SIL Open Font License 1.1",
-    },
-    {
-      key: "OFL-1.1-RFN",
-      name: "SIL Open Font License 1.1 with Reserved Font Name",
-    },
-    {
-      key: "OFL-1.1-no-RFN",
-      name: "SIL Open Font License 1.1 with no Reserved Font Name",
-    },
-    {
-      key: "SNIA",
-      name: "SNIA Public License 1.1",
-    },
-    {
-      key: "blessing",
-      name: "SQLite Blessing",
-    },
-    {
-      key: "SSH-OpenSSH",
-      name: "SSH OpenSSH license",
-    },
-    {
-      key: "SSH-short",
-      name: "SSH short notice",
-    },
-    {
-      key: "SAX-PD",
-      name: "Sax Public Domain Notice",
-    },
-    {
-      key: "Saxpath",
-      name: "Saxpath License",
-    },
-    {
-      key: "SWL",
-      name: "Scheme Widget Library (SWL) Software License Agreement",
-    },
-    {
-      key: "SMPPL",
-      name: "Secure Messaging Protocol Public License",
-    },
-    {
-      key: "Sendmail",
-      name: "Sendmail License",
-    },
-    {
-      key: "Sendmail-8.23",
-      name: "Sendmail License 8.23",
-    },
-    {
-      key: "SSPL-1.0",
-      name: "Server Side Public License, v 1",
-    },
-    {
-      key: "SimPL-2.0",
-      name: "Simple Public License 2.0",
-    },
-    {
-      key: "Sleepycat",
-      name: "Sleepycat License",
-    },
-    {
-      key: "SHL-0.5",
-      name: "Solderpad Hardware License v0.5",
-    },
-    {
-      key: "SHL-0.51",
-      name: "Solderpad Hardware License, Version 0.51",
-    },
-    {
-      key: "Spencer-86",
-      name: "Spencer License 86",
-    },
-    {
-      key: "Spencer-94",
-      name: "Spencer License 94",
-    },
-    {
-      key: "Spencer-99",
-      name: "Spencer License 99",
-    },
-    {
-      key: "SMLNJ",
-      name: "Standard ML of New Jersey License",
-    },
-    {
-      key: "StandardML-NJ",
-      name: "Standard ML of New Jersey License",
-    },
-    {
-      key: "SugarCRM-1.1.3",
-      name: "SugarCRM Public License v1.1.3",
-    },
-    {
-      key: "SISSL",
-      name: "Sun Industry Standards Source License v1.1",
-    },
-    {
-      key: "SISSL-1.2",
-      name: "Sun Industry Standards Source License v1.2",
-    },
-    {
-      key: "SPL-1.0",
-      name: "Sun Public License v1.0",
-    },
-    {
-      key: "Watcom-1.0",
-      name: "Sybase Open Watcom Public License 1.0",
-    },
-    {
-      key: "TAPR-OHL-1.0",
-      name: "TAPR Open Hardware License v1.0",
-    },
-    {
-      key: "TCL",
-      name: "TCL/TK License",
-    },
-    {
-      key: "TCP-wrappers",
-      name: "TCP Wrappers License",
-    },
-    {
-      key: "TMate",
-      name: "TMate Open Source License",
-    },
-    {
-      key: "TORQUE-1.1",
-      name: "TORQUE v2.5+ Software License v1.1",
-    },
-    {
-      key: "OGDL-Taiwan-1.0",
-      name: "Taiwan Open Government Data License, version 1.0",
-    },
-    {
-      key: "TU-Berlin-1.0",
-      name: "Technische Universitaet Berlin License 1.0",
-    },
-    {
-      key: "TU-Berlin-2.0",
-      name: "Technische Universitaet Berlin License 2.0",
-    },
-    {
-      key: "MirOS",
-      name: "The MirOS Licence",
-    },
-    {
-      key: "Parity-6.0.0",
-      name: "The Parity Public License 6.0.0",
-    },
-    {
-      key: "Parity-7.0.0",
-      name: "The Parity Public License 7.0.0",
-    },
-    {
-      key: "Unlicense",
-      name: "The Unlicense",
-    },
-    {
-      key: "TOSL",
-      name: "Trusster Open Source License",
-    },
-    {
-      key: "Unicode-DFS-2015",
-      name: "Unicode License Agreement - Data Files and Software (2015)",
-    },
-    {
-      key: "Unicode-DFS-2016",
-      name: "Unicode License Agreement - Data Files and Software (2016)",
-    },
-    {
-      key: "Unicode-TOU",
-      name: "Unicode Terms of Use",
-    },
-    {
-      key: "UPL-1.0",
-      name: "Universal Permissive License v1.0",
-    },
-    {
-      key: "NCSA",
-      name: "University of Illinois/NCSA Open Source License",
-    },
-    {
-      key: "UCL-1.0",
-      name: "Upstream Compatibility License v1.0",
-    },
-    {
-      key: "VOSTROM",
-      name: "VOSTROM Public License for Open Source",
-    },
-    {
-      key: "Vim",
-      name: "Vim License",
-    },
-    {
-      key: "VSL-1.0",
-      name: "Vovida Software License v1.0",
-    },
-    {
-      key: "W3C-20150513",
-      name: "W3C Software Notice and Document License (2015-05-13)",
-    },
-    {
-      key: "W3C-19980720",
-      name: "W3C Software Notice and License (1998-07-20)",
-    },
-    {
-      key: "W3C",
-      name: "W3C Software Notice and License (2002-12-31)",
-    },
-    {
-      key: "Wsuipa",
-      name: "Wsuipa License",
-    },
-    {
-      key: "Xnet",
-      name: "X.Net License",
-    },
-    {
-      key: "X11",
-      name: "X11 License",
-    },
-    {
-      key: "XFree86-1.1",
-      name: "XFree86 License 1.1",
-    },
-    {
-      key: "xpp",
-      name: "XPP License",
-    },
-    {
-      key: "XSkat",
-      name: "XSkat License",
-    },
-    {
-      key: "Xerox",
-      name: "Xerox License",
-    },
-    {
-      key: "YPL-1.0",
-      name: "Yahoo! Public License v1.0",
-    },
-    {
-      key: "YPL-1.1",
-      name: "Yahoo! Public License v1.1",
-    },
-    {
-      key: "Zed",
-      name: "Zed License",
-    },
-    {
-      key: "Zend-2.0",
-      name: "Zend License v2.0",
-    },
-    {
-      key: "Zimbra-1.3",
-      name: "Zimbra Public License v1.3",
-    },
-    {
-      key: "Zimbra-1.4",
-      name: "Zimbra Public License v1.4",
-    },
-    {
-      key: "ZPL-1.1",
-      name: "Zope Public License 1.1",
-    },
-    {
-      key: "ZPL-2.0",
-      name: "Zope Public License 2.0",
-    },
-    {
-      key: "ZPL-2.1",
-      name: "Zope Public License 2.1",
-    },
-    {
-      key: "bzip2-1.0.5",
-      name: "bzip2 and libbzip2 License v1.0.5",
-    },
-    {
-      key: "bzip2-1.0.6",
-      name: "bzip2 and libbzip2 License v1.0.6",
-    },
-    {
-      key: "copyleft-next-0.3.0",
-      name: "copyleft-next 0.3.0",
-    },
-    {
-      key: "copyleft-next-0.3.1",
-      name: "copyleft-next 0.3.1",
-    },
-    {
-      key: "curl",
-      name: "curl License",
-    },
-    {
-      key: "diffmark",
-      name: "diffmark license",
-    },
-    {
-      key: "dvipdfm",
-      name: "dvipdfm License",
-    },
-    {
-      key: "eCos-2.0",
-      name: "eCos license version 2.0",
-    },
-    {
-      key: "eGenix",
-      name: "eGenix.com Public License 1.1.0",
-    },
-    {
-      key: "MIT-enna",
-      name: "enna License",
-    },
-    {
-      key: "MIT-feh",
-      name: "feh License",
-    },
-    {
-      key: "gSOAP-1.3b",
-      name: "gSOAP Public License v1.3b",
-    },
-    {
-      key: "gnuplot",
-      name: "gnuplot License",
-    },
-    {
-      key: "iMatix",
-      name: "iMatix Standard Function Library Agreement",
-    },
-    {
-      key: "Libpng",
-      name: "libpng License",
-    },
-    {
-      key: "libselinux-1.0",
-      name: "libselinux public domain notice",
-    },
-    {
-      key: "libtiff",
-      name: "libtiff License",
-    },
-    {
-      key: "mpich2",
-      name: "mpich2 License",
-    },
-    {
-      key: "psfrag",
-      name: "psfrag License",
-    },
-    {
-      key: "psutils",
-      name: "psutils License",
-    },
-    {
-      key: "wxWindows",
-      name: "wxWindows Library License",
-    },
-    {
-      key: "xinetd",
-      name: "xinetd License",
-    },
-    {
-      key: "Zlib",
-      name: "zlib License",
-    },
-    {
-      key: "zlib-acknowledgement",
-      name: "zlib/libpng License with Acknowledgement",
-    },
-  ],
-  links: {
-    contact: ["mailto:hello@example.com"],
-    donations: ["https://example.com/donate"],
-    issues: ["https://github.com/issues"],
-    source: ["https://github.com"],
-    website: ["https://example.com", "https://example.com/hey"],
-  },
-  private: false,
-  public_metrics_blacklist: [
-    "weekly_installed_base_by_operating_system_normalized",
-  ],
-  public_metrics_enabled: false,
-  publisher_name: "John Doe",
-  screenshot_urls: [
-    "https://dashboard.snapcraft.io/site_media/appmedia/2022/08/screenshot-yellow_bwcSz5T.jpg",
-    "https://dashboard.snapcraft.io/site_media/appmedia/2022/08/too-big_ASpc8iL.gif",
-    "https://dashboard.snapcraft.io/site_media/appmedia/2023/03/screenshot-green.jpg",
-    "https://dashboard.snapcraft.io/site_media/appmedia/2024/03/screenshot-blue-1709564416.jpg",
-    "https://dashboard.snapcraft.io/site_media/appmedia/2024/06/screenshot-1718185318.jpg",
-  ],
-  snap_categories: {
-    categories: ["health-and-fitness", "music-and-audio"],
-    locked: false,
-  },
-  snap_id: "bv9Q2i9CNAvTjt9wTx1cFC6SAT9YrEfG",
-  snap_name: "test-snap",
-  snap_title: "test-snap",
-  status: "published",
-  summary: "The snap I use for testingd",
-  tour_steps: [
-    {
-      content:
-        "<p>Here you can manage the display of your snap listing within the store.</p>\n<p>We’ll give you a quick tour to get you up to speed!</p>\n",
-      id: "listing-intro",
-      title: "Welcome to your snap listing page!",
-    },
-    {
-      content:
-        "<p>Including an icon will help your snap to stand out making it far more attractive to users browsing graphical interfaces such as snapcraft.io/store and the Snap Store.</p>\n",
-      id: "listing-icon",
-      title: "Icons attract eyes…",
-    },
-    {
-      content:
-        "<p>Adding a meaningful title to your snap listing will help people understand what the purpose of your snap is.</p>\n<p>It's best to use something that aligns with your brand and looks clean. This is your opportunity to replace punctuation with spaces and capitalise.</p>\n",
-      id: "listing-title",
-      title: "Title your snap",
-    },
-    {
-      content:
-        "<p>Categories are used to define the kind of application you have published. Categorising your snap will aid findability within the Store and increase exposure to end users.</p>\n",
-      id: "listing-category",
-      title: "Set your snap category",
-    },
-    {
-      content:
-        "<p>Allow potential users get a better understanding of features and functionality prior to installation. Snaps that utilise a video tend to have a higher number of installs and better user retention.</p>\n",
-      id: "listing-video",
-      title: "Showcase your application with a video",
-    },
-    {
-      content:
-        "<p>Explain your application visually and allow users to see what they will get prior to installation. Data shows that snaps with images tend to have a bigger install base.</p>\n",
-      id: "listing-images",
-      title: "Celebrate key features with images",
-    },
-    {
-      content:
-        "<p>Adding a banner will increase your chances of being featured on snapcraft.io and in GNOME software.</p>\n",
-      id: "listing-banner",
-      title: "Get featured, get installed!",
-    },
-    {
-      content:
-        "<p>Having a relevant and descriptive summary will allow users to get a quick insight into what your snap does. This should mean that you have more target users clicking through to your listing page.</p>\n",
-      id: "listing-summary",
-      title: "Summarise your application",
-    },
-    {
-      content:
-        "<p>Providing a detailed description allows your users to understand the core functionality of your snap. It’s especially useful if it doesn’t have a user interface or if you don’t have any media assets to upload.</p>\n",
-      id: "listing-description",
-      title: "Get into the details with your description",
-    },
-    {
-      content:
-        "<p>Give users the opportunity to learn more about your application and find support when needed.</p>\n<p>Alternatively, you can add an email address if you prefer direct contact.</p>\n",
-      id: "listing-contact",
-      position: "top-left",
-      title: "Feeling sociable? Add your contact information",
-    },
-    {
-      content:
-        "<p>If you ever need more help just look for the tour icon.</p>\n",
-      id: "tour-end",
-      position: "top-right",
-      title: "That’s it for now!",
-    },
-  ],
-  update_metadata_on_release: false,
-  username: "steverydz",
-  video_urls: ["https://www.youtube.com/watch?v=oTahLEX3NXos"],
-  website: "https://steverydz.com",
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/CategoriesInput/CategoriesInput.tsx.html b/coverage/js/publisher/listing/components/CategoriesInput/CategoriesInput.tsx.html deleted file mode 100644 index 9a16a8f2d..000000000 --- a/coverage/js/publisher/listing/components/CategoriesInput/CategoriesInput.tsx.html +++ /dev/null @@ -1,532 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/CategoriesInput/CategoriesInput.tsx - - - - - - - - - -
-
-

All files / publisher/listing/components/CategoriesInput CategoriesInput.tsx

-
- -
- 100% - Statements - 13/13 -
- - -
- 77.77% - Branches - 14/18 -
- - -
- 100% - Functions - 6/6 -
- - -
- 100% - Lines - 13/13 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -38x -38x -  -  -  -38x -38x -  -  -  -38x -  -  -  -38x -14x -  -  -38x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -554x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -529x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { useState, useEffect } from "react";
-import { nanoid } from "nanoid";
-import { Row, Col, Button, Icon } from "@canonical/react-components";
- 
-type Props = {
-  register: Function;
-  getFieldState: Function;
-  primaryCategory: string;
-  secondaryCategory: string;
-  setValue: Function;
-  categories: Array<{
-    slug: string;
-    name: string;
-  }>;
-};
- 
-function CategoriesInput({
-  categories,
-  register,
-  getFieldState,
-  setValue,
-  primaryCategory,
-  secondaryCategory,
-}: Props) {
-  const primaryCategoryFieldId = nanoid();
-  const primaryCategoryFieldState = getFieldState
-    ? getFieldState("primary-category")
-    : "";
- 
-  const secondaryCategoryFieldId = nanoid();
-  const secondaryCategoryFieldState = getFieldState
-    ? getFieldState("secondary-category")
-    : "";
- 
-  const [showSecondCategoryField, setShowSecondCategoryField] = useState(
-    secondaryCategory ? true : false
-  );
- 
-  useEffect(() => {
-    setShowSecondCategoryField(secondaryCategory ? true : false);
-  }, [secondaryCategory]);
- 
-  return (
-    <>
-      <Row
-        className={`p-form__group ${
-          primaryCategoryFieldState.invalid && "p-form-validation is-error"
-        }`}
-      >
-        <Col size={2} data-tour="listing-category">
-          <label htmlFor={primaryCategoryFieldId} className="p-form__label">
-            Category:
-          </label>
-        </Col>
-        <Col size={5}>
-          <div className="p-form__control" data-tour="listing-category">
-            <select
-              name="primary-category"
-              id={primaryCategoryFieldId}
-              {...register("primary-category")}
-              defaultValue={primaryCategory}
-            >
-              <option value="">Select a category</option>
-              {categories.map((category) => (
-                <option
-                  key={category.slug}
-                  value={category.slug}
-                  disabled={category.slug === secondaryCategory}
-                >
-                  {category.name}
-                </option>
-              ))}
-              <option value="">None</option>
-            </select>
-          </div>
-          {!showSecondCategoryField && (
-            <>
-              <Button
-                appearance="link"
-                onClick={() => {
-                  setShowSecondCategoryField(true);
-                }}
-                data-testid="add-category-button"
-              >
-                +&nbsp;Add another category
-              </Button>
-              <p className="p-form-help-text">
-                If your snap fits into multiple categories you can select
-                another.
-              </p>
-            </>
-          )}
-        </Col>
-      </Row>
-      {showSecondCategoryField && (
-        <Row
-          className={`p-form__group ${
-            secondaryCategoryFieldState.invalid && "p-form-validation is-error"
-          }`}
-        >
-          <Col size={2}>
-            <label htmlFor={secondaryCategoryFieldId} className="p-form__label">
-              Second category:
-            </label>
-          </Col>
-          <Col size={5}>
-            <div className="p-form__control">
-              <select
-                name="secondary-category"
-                id={secondaryCategoryFieldId}
-                {...register("secondary-category")}
-                defaultValue={secondaryCategory}
-              >
-                <option value="">Select a category</option>
-                {categories.map((category) => (
-                  <option
-                    key={category.slug}
-                    value={category.slug}
-                    disabled={category.slug === primaryCategory}
-                  >
-                    {category.name}
-                  </option>
-                ))}
-                <option value="">None</option>
-              </select>
-            </div>
-          </Col>
-          <Col size={2}>
-            <Button
-              appearance="base"
-              onClick={() => {
-                setValue("secondary-category", "", {
-                  shouldDirty:
-                    secondaryCategoryFieldState.isDirty || secondaryCategory,
-                });
-                setShowSecondCategoryField(false);
-              }}
-              data-testid="delete-category-button"
-            >
-              <Icon name="delete">Delete second category</Icon>
-            </Button>
-          </Col>
-        </Row>
-      )}
-    </>
-  );
-}
- 
-export default CategoriesInput;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/CategoriesInput/index.html b/coverage/js/publisher/listing/components/CategoriesInput/index.html deleted file mode 100644 index 211883acb..000000000 --- a/coverage/js/publisher/listing/components/CategoriesInput/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/CategoriesInput - - - - - - - - - -
-
-

All files publisher/listing/components/CategoriesInput

-
- -
- 100% - Statements - 13/13 -
- - -
- 77.77% - Branches - 14/18 -
- - -
- 100% - Functions - 6/6 -
- - -
- 100% - Lines - 13/13 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
CategoriesInput.tsx -
-
100%13/1377.77%14/18100%6/6100%13/13
index.ts -
-
0%0/00%0/00%0/00%0/0
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/ListingDescriptionField/ListingDescriptionField.tsx.html b/coverage/js/publisher/listing/components/ContactInformation/ContactFields.tsx.html similarity index 67% rename from coverage/js/publisher/listing/components/ListingDescriptionField/ListingDescriptionField.tsx.html rename to coverage/js/publisher/listing/components/ContactInformation/ContactFields.tsx.html index 4536acf80..74192829b 100644 --- a/coverage/js/publisher/listing/components/ListingDescriptionField/ListingDescriptionField.tsx.html +++ b/coverage/js/publisher/listing/components/ContactInformation/ContactFields.tsx.html @@ -3,7 +3,7 @@ - Code coverage report for publisher/listing/components/ListingDescriptionField/ListingDescriptionField.tsx + Code coverage report for publisher/listing/components/ContactInformation/ContactFields.tsx @@ -19,34 +19,34 @@
-

All files / publisher/listing/components/ListingDescriptionField ListingDescriptionField.tsx

+

All files / publisher/listing/components/ContactInformation ContactFields.tsx

- 80% + 50% Statements - 4/5 + 3/6
- 50% + 75% Branches - 3/6 + 6/8
- 50% + 40% Functions - 1/2 + 2/5
- 80% + 50% Lines - 4/5 + 3/6
@@ -61,7 +61,7 @@

All files / publis

-
+
1 2 @@ -151,7 +151,21 @@

All files / publis 86 87 88 -89

  +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102  +        @@ -161,11 +175,7 @@

All files / publis       -26x -26x -26x   -26x       @@ -178,10 +188,12 @@

All files / publis       +25x         +25x       @@ -203,6 +215,11 @@

All files / publis       +25x +  +  +  +        @@ -218,6 +235,12 @@

All files / publis       +  +  +  +  +  +        @@ -229,6 +252,9 @@

All files / publis       +  +  +        @@ -239,94 +265,107 @@

All files / publis       - 

import { useState } from "react";
-import { nanoid } from "nanoid";
-import { Row, Col, Button } from "@canonical/react-components";
+ 
import {
+  Control,
+  FieldValues,
+  useFieldArray,
+  UseFormGetValues,
+  UseFormRegister,
+} from "react-hook-form";
+import { Row, Col, Button, Icon } from "@canonical/react-components";
  
 type Props = {
-  register: Function;
-  getFieldState: Function;
+  register: UseFormRegister<FieldValues>;
+  control: Control<FieldValues>;
+  labelName: string;
+  fieldName: string;
+  getValues: UseFormGetValues<FieldValues>;
 };
  
-function ListingDescriptionField({ register, getFieldState }: Props) {
-  const id = nanoid();
-  const fieldState = getFieldState ? getFieldState("description") : "";
-  const [showMarkdownGuide, setShowMarkdownGuide] = useState(false);
+function ContactFields({
+  register,
+  control,
+  labelName,
+  fieldName,
+  getValues,
+}: Props): JSX.Element {
+  const { fields, append, remove } = useFieldArray({
+    control,
+    name: fieldName,
+  });
  
   return (
-    <Row
-      className={`p-form__group ${
-        fieldState.invalid && "p-form-validation is-error"
-      }`}
-    >
-      <Col size={2} data-tour="listing-description">
-        <label htmlFor={id} className="p-form__label">
-          Description:
-        </label>
-      </Col>
-      <Col size={8}>
-        <div className="p-form__control">
-          <textarea
-            data-tour="listing-description"
-            id={id}
-            className="p-form-validation__input"
-            rows={10}
-            {...register("description", { required: true })}
-          />
-        </div>
-        <p className="p-form-help-text u-no-margin--bottom">
-          <Button
-            type="button"
-            appearance="link"
-            small={true}
-            className="u-no-padding--left u-no-padding--right"
-            onClick={() => {
-              setShowMarkdownGuide(!showMarkdownGuide);
-            }}
-          >
-            Show supported markdown syntax
-          </Button>
-        </p>
-        {showMarkdownGuide && (
-          <Row>
-            <Col size={4}>
-              <p>
-                <small>
-                  <strong>Bold</strong>: <code>**Foo**</code>
-                </small>
-              </p>
-              <p>
-                <small>
-                  <strong>URLs</strong>: <code>https://foo.bar</code>
-                </small>
-              </p>
-              <p>
-                <small>
-                  <strong>Lists</strong>: <code>* Foo</code>
-                </small>
-              </p>
-            </Col>
-            <Col size={4}>
-              <p>
-                <small>
-                  <strong>Italics</strong>: <code>_Foo_</code>
-                </small>
-              </p>
-              <p>
-                <small>
-                  <strong>Code</strong>: Text indented with 3 spaces of inside{" "}
-                  <code>`</code>
-                </small>
-              </p>
+    <>
+      {fields.length === 0 && (
+        <Row className="p-form__group">
+          <Col size={2}>
+            <label htmlFor={fieldName}>{labelName}:</label>
+          </Col>
+          <Col size={5}>
+            <Button
+              type="button"
+              appearance="link"
+              onClick={() => {
+                append({ url: "" });
+              }}
+            >
+              +&nbsp;Add field
+            </Button>
+          </Col>
+        </Row>
+      )}
+ 
+      {fields.map((field, index) => (
+        <Row className="p-form__group" key={field.id}>
+          {index === 0 && (
+            <Col size={2}>
+              <label htmlFor={fieldName}>{labelName}:</label>
             </Col>
-          </Row>
-        )}
-      </Col>
-    </Row>
+          )}
+          <Col size={5} emptyLarge={index === 0 ? undefined : 3}>
+            <div className="p-form__control">
+              <input
+                type="url"
+                {...register(`${fieldName}.${index}.url`)}
+                defaultValue={getValues(`${fieldName}.${index}.url`)}
+              />
+            </div>
+          </Col>
+          <Col size={2}>
+            <Button
+              type="button"
+              appearance="base"
+              onClick={() => {
+                remove(index);
+              }}
+            >
+              <Icon name="delete" />
+              <span className="u-off-screen">Remove this link</span>
+            </Button>
+          </Col>
+        </Row>
+      ))}
+ 
+      {fields.length > 0 && (
+        <Row>
+          <Col size={5} emptyLarge={3}>
+            <Button
+              type="button"
+              appearance="link"
+              onClick={() => {
+                append({ url: "" });
+              }}
+            >
+              +&nbsp;Add field
+            </Button>
+          </Col>
+        </Row>
+      )}
+    </>
   );
 }
  
-export default ListingDescriptionField;
+export default ContactFields;
  
@@ -334,7 +373,7 @@

All files / publis - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/ImageUpload/index.ts.html b/coverage/js/publisher/listing/components/ImageUpload/index.ts.html deleted file mode 100644 index 5e9fc0e36..000000000 --- a/coverage/js/publisher/listing/components/ImageUpload/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/ImageUpload/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/components/ImageUpload index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./ImageUpload";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/LicenseInputs/index.html b/coverage/js/publisher/listing/components/LicenseInputs/index.html deleted file mode 100644 index 93414ed1a..000000000 --- a/coverage/js/publisher/listing/components/LicenseInputs/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/LicenseInputs - - - - - - - - - -
-
-

All files publisher/listing/components/LicenseInputs

-
- -
- 42.37% - Statements - 25/59 -
- - -
- 27.27% - Branches - 6/22 -
- - -
- 44.82% - Functions - 13/29 -
- - -
- 40% - Lines - 22/55 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
LicenseInputs.tsx -
-
76.92%10/1375%3/466.66%4/675%9/12
LicenseSearch.tsx -
-
32.6%15/4616.66%3/1839.13%9/2330.23%13/43
index.ts -
-
0%0/00%0/00%0/00%0/0
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/LicenseInputs/index.ts.html b/coverage/js/publisher/listing/components/LicenseInputs/index.ts.html deleted file mode 100644 index ab892851b..000000000 --- a/coverage/js/publisher/listing/components/LicenseInputs/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/LicenseInputs/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/components/LicenseInputs index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./LicenseInputs";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/ListingDescriptionField/index.html b/coverage/js/publisher/listing/components/ListingDescriptionField/index.html deleted file mode 100644 index 3fc2d0d9b..000000000 --- a/coverage/js/publisher/listing/components/ListingDescriptionField/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/ListingDescriptionField - - - - - - - - - -
-
-

All files publisher/listing/components/ListingDescriptionField

-
- -
- 80% - Statements - 4/5 -
- - -
- 50% - Branches - 3/6 -
- - -
- 50% - Functions - 1/2 -
- - -
- 80% - Lines - 4/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
ListingDescriptionField.tsx -
-
80%4/550%3/650%1/280%4/5
index.ts -
-
0%0/00%0/00%0/00%0/0
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/ListingDescriptionField/index.ts.html b/coverage/js/publisher/listing/components/ListingDescriptionField/index.ts.html deleted file mode 100644 index b895335c6..000000000 --- a/coverage/js/publisher/listing/components/ListingDescriptionField/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/ListingDescriptionField/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/components/ListingDescriptionField index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./ListingDescriptionField";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/ImageUpload/ImageUpload.tsx.html b/coverage/js/publisher/listing/components/ListingDetails/ImageUpload.tsx.html similarity index 92% rename from coverage/js/publisher/listing/components/ImageUpload/ImageUpload.tsx.html rename to coverage/js/publisher/listing/components/ListingDetails/ImageUpload.tsx.html index 7c77cb3ff..3bcfecacf 100644 --- a/coverage/js/publisher/listing/components/ImageUpload/ImageUpload.tsx.html +++ b/coverage/js/publisher/listing/components/ListingDetails/ImageUpload.tsx.html @@ -3,7 +3,7 @@ - Code coverage report for publisher/listing/components/ImageUpload/ImageUpload.tsx + Code coverage report for publisher/listing/components/ListingDetails/ImageUpload.tsx @@ -19,34 +19,34 @@
-

All files / publisher/listing/components/ImageUpload ImageUpload.tsx

+

All files / publisher/listing/components/ListingDetails ImageUpload.tsx

- 26.82% + 23.4% Statements - 11/41 + 11/47
- 54.34% + 52.08% Branches - 25/46 + 25/48
- 10% + 8.33% Functions - 1/10 + 1/12
- 26.82% + 23.4% Lines - 11/41 + 11/47
@@ -389,7 +389,23 @@

All files / publis 324 325 326 -327  +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343        @@ -434,6 +450,18 @@

All files / publis       +  +  +  +  +  +  +  +  +  +  +  +        @@ -447,24 +475,28 @@

All files / publis       -52x -52x -52x -52x -52x -52x   -52x -52x   -52x     +10x +10x +10x +10x +10x +10x   +10x +10x   +10x     -52x +  +  +  +  +10x       @@ -510,7 +542,7 @@

All files / publis       -52x +10x       @@ -716,6 +748,7 @@

All files / publis      
import { useState, SyntheticEvent } from "react";
+import { UseFormRegister, UseFormSetValue, FieldValues } from "react-hook-form";
 import { nanoid } from "nanoid";
 import {
   Row,
@@ -725,16 +758,12 @@ 

All files / publis Icon, } from "@canonical/react-components";   -import { - validateImageDimensions, - validateAspectRatio, - formatFileSize, -} from "../../utils"; +import { validateImageDimensions } from "../../utils";   type Props = { imageUrl: string | null; - register: Function; - setValue: Function; + register: UseFormRegister<FieldValues>; + setValue: UseFormSetValue<FieldValues>; validationSchema: { maxFileSize: number; minWidth: number; @@ -758,6 +787,25 @@

All files / publis hasDarkThemePreview?: boolean; };   +function validateAspectRatio( + width: number, + height: number, + ratio: { width: number; height: number } +): boolean { + const aspectRatio = ratio.width / ratio.height; + const expectedHeight = width / aspectRatio; +  + return expectedHeight === height; +} +  +function formatFileSize(fileSize: number): string { + if (fileSize < 1000000) { + return `${fileSize / 1000}kB`; + } +  + return `${fileSize / 1000000}MB`; +} +  function ImageUpload({ imageUrl, register, @@ -1048,7 +1096,7 @@

All files / publis + + + + + + \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/Screenshots/Screenshot.tsx.html b/coverage/js/publisher/listing/components/ListingDetails/Screenshot.tsx.html similarity index 95% rename from coverage/js/publisher/listing/components/Screenshots/Screenshot.tsx.html rename to coverage/js/publisher/listing/components/ListingDetails/Screenshot.tsx.html index 518acff0b..845dc75e2 100644 --- a/coverage/js/publisher/listing/components/Screenshots/Screenshot.tsx.html +++ b/coverage/js/publisher/listing/components/ListingDetails/Screenshot.tsx.html @@ -3,7 +3,7 @@ - Code coverage report for publisher/listing/components/Screenshots/Screenshot.tsx + Code coverage report for publisher/listing/components/ListingDetails/Screenshot.tsx @@ -19,7 +19,7 @@
-

All files / publisher/listing/components/Screenshots Screenshot.tsx

+

All files / publisher/listing/components/ListingDetails Screenshot.tsx

@@ -30,9 +30,9 @@

All files / publis
- 35.71% + 85.71% Branches - 5/14 + 12/14
@@ -193,16 +193,16 @@

All files / publis       -130x +25x   -130x +25x         -130x +25x   -130x +25x       @@ -308,7 +308,7 @@

All files / publis   return ( <div - ref={screenshotUrl ? setNodeRef : null} + ref={screenshotUrl ? setNodeRef : null} style={style} {...attributes} className="snap-image-upload-container p-listing-images__image" @@ -333,7 +333,7 @@

All files / publis </div> </div> ) : ( - <div + <div className="snap-add-image" style={{ width: "132px", @@ -347,7 +347,7 @@

All files / publis )}   {!screenshotUrl && ( - <input + <input type="file" disabled={screenshotUrl || index > screenshotUrls.length} accept="image/gif, image/png, image/jpeg" @@ -382,7 +382,7 @@

All files / publis - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/MetricsInputs/index.html b/coverage/js/publisher/listing/components/MetricsInputs/index.html deleted file mode 100644 index 390e13be4..000000000 --- a/coverage/js/publisher/listing/components/MetricsInputs/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/MetricsInputs - - - - - - - - - -
-
-

All files publisher/listing/components/MetricsInputs

-
- -
- 36% - Statements - 9/25 -
- - -
- 0% - Branches - 0/20 -
- - -
- 28.57% - Functions - 2/7 -
- - -
- 36% - Lines - 9/25 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
MetricsInputs.tsx -
-
36%9/250%0/2028.57%2/736%9/25
index.ts -
-
0%0/00%0/00%0/00%0/0
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/MetricsInputs/index.ts.html b/coverage/js/publisher/listing/components/MetricsInputs/index.ts.html deleted file mode 100644 index 5f6ddf249..000000000 --- a/coverage/js/publisher/listing/components/MetricsInputs/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/MetricsInputs/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/components/MetricsInputs index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./MetricsInputs";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/PreviewForm/PreviewForm.tsx.html b/coverage/js/publisher/listing/components/PreviewForm/PreviewForm.tsx.html index e3f069812..ae1c6cd75 100644 --- a/coverage/js/publisher/listing/components/PreviewForm/PreviewForm.tsx.html +++ b/coverage/js/publisher/listing/components/PreviewForm/PreviewForm.tsx.html @@ -166,7 +166,17 @@

All files / publis 101 102 103 -104  +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114        @@ -192,18 +202,18 @@

All files / publis       -26x     -26x -26x +5x   -26x   -26x -26x +5x +5x   +5x   +5x +5x       @@ -219,37 +229,47 @@

All files / publis       -26x   -26x -26x -130x       +5x   +5x +5x +5x       -26x -26x   -26x -26x     -26x -26x   +5x +5x   -26x +5x +5x         -26x   -26x +5x +5x +  +  +  +  +  +5x +  +  +  +  +5x +  +5x       @@ -277,7 +297,7 @@

All files / publis };   type ListingData = { - categories: Array<string>; + categories: { name: string; slug: string }[]; links: { website: Array<string>; contact: Array<string>; @@ -292,6 +312,8 @@

All files / publis type: string; status: string; }>; + summary: string; + description: string; };   function PreviewForm({ snapName, getValues }: Props) { @@ -303,7 +325,7 @@

All files / publis donations: getValues("donations").map( (item: { url: string }) => item.url ), - source: getValues("source-code").map((item: { url: string }) => item.url), + source: getValues("source_code").map((item: { url: string }) => item.url), issues: getValues("issues").map((item: { url: string }) => item.url), }, snap_name: snapName, @@ -320,6 +342,8 @@

All files / publis status: "uploaded", }, ], + summary: getValues("summary"), + description: getValues("description"), };   const screenshotUrls = getValues("screenshot_urls"); @@ -334,15 +358,21 @@

All files / publis }); }   - const primaryCategory = getValues("primary-category"); - const secondaryCategory = getValues("secondary-category"); + const primaryCategory = getValues("primary_category"); + const secondaryCategory = getValues("secondary_category");   Eif (primaryCategory) { - listingData.categories.push(primaryCategory); + listingData.categories.push({ + name: primaryCategory, + slug: primaryCategory, + }); }   Eif (secondaryCategory) { - listingData.categories.push(secondaryCategory); + listingData.categories.push({ + name: secondaryCategory, + slug: secondaryCategory, + }); }   window.localStorage.setItem( @@ -379,7 +409,7 @@

All files / publis - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/PrimaryDomainInput/index.ts.html b/coverage/js/publisher/listing/components/PrimaryDomainInput/index.ts.html deleted file mode 100644 index 785c517c6..000000000 --- a/coverage/js/publisher/listing/components/PrimaryDomainInput/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/PrimaryDomainInput/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/components/PrimaryDomainInput index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./PrimaryDomainInput";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/UrlInput/UrlInput.tsx.html b/coverage/js/publisher/listing/components/UrlInput/UrlInput.tsx.html deleted file mode 100644 index 86d477ad2..000000000 --- a/coverage/js/publisher/listing/components/UrlInput/UrlInput.tsx.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/UrlInput/UrlInput.tsx - - - - - - - - - -
-
-

All files / publisher/listing/components/UrlInput UrlInput.tsx

-
- -
- 100% - Statements - 4/4 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 4/4 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34  -  -  -  -  -  -  -  -104x -104x -104x -  -104x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
type Props = {
-  fieldName: string;
-  index: number;
-  register: Function;
-  getFieldState: Function;
-};
- 
-function UrlInput({ fieldName, index, register, getFieldState }: Props) {
-  const name = `${fieldName}.${index}.url`;
-  const fieldState = getFieldState(name);
-  const isInvalid = fieldState.invalid;
- 
-  return (
-    <div
-      className={`p-form__group ${isInvalid && "p-form-validation is-error"}`}
-    >
-      <input
-        type="url"
-        id={name}
-        className="p-form-validation__input"
-        {...register(name, {
-          required: false,
-          pattern: { value: /^https?:\/\//gi },
-        })}
-      />
-      {fieldState.invalid && (
-        <p className="p-form-validation__message">Please enter a valid URL</p>
-      )}
-    </div>
-  );
-}
- 
-export default UrlInput;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/UrlInput/index.html b/coverage/js/publisher/listing/components/UrlInput/index.html deleted file mode 100644 index 1f8d6fde3..000000000 --- a/coverage/js/publisher/listing/components/UrlInput/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/UrlInput - - - - - - - - - -
-
-

All files publisher/listing/components/UrlInput

-
- -
- 100% - Statements - 4/4 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 4/4 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
UrlInput.tsx -
-
100%4/450%2/4100%1/1100%4/4
index.ts -
-
0%0/00%0/00%0/00%0/0
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/components/UrlInput/index.ts.html b/coverage/js/publisher/listing/components/UrlInput/index.ts.html deleted file mode 100644 index f6e906c6a..000000000 --- a/coverage/js/publisher/listing/components/UrlInput/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/components/UrlInput/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/components/UrlInput index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./UrlInput";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/hooks/index.html b/coverage/js/publisher/listing/hooks/index.html index 61c468ce1..3efd4d6b3 100644 --- a/coverage/js/publisher/listing/hooks/index.html +++ b/coverage/js/publisher/listing/hooks/index.html @@ -23,30 +23,30 @@

All files publisher/listing/hooks

- 33.33% + 5.88% Statements - 2/6 + 2/34
0% Branches - 0/2 + 0/18
- 100% + 28.57% Functions - 2/2 + 2/7
- 33.33% + 5.88% Lines - 2/6 + 2/34
@@ -93,19 +93,34 @@

All files publisher/listing/hooks

0/0 + + useMutateListingData.ts + +
+ + 3.57% + 1/28 + 0% + 0/16 + 20% + 1/5 + 3.57% + 1/28 + + useVerified.ts - -
+ +
- 33.33% - 2/6 + 16.66% + 1/6 0% 0/2 - 100% - 2/2 - 33.33% - 2/6 + 50% + 1/2 + 16.66% + 1/6 @@ -116,7 +131,7 @@

All files publisher/listing/hooks

+ - - + + \ No newline at end of file diff --git a/coverage/js/publisher/listing/hooks/useVerified.ts.html b/coverage/js/publisher/listing/hooks/useVerified.ts.html index d9654110a..00a38b11b 100644 --- a/coverage/js/publisher/listing/hooks/useVerified.ts.html +++ b/coverage/js/publisher/listing/hooks/useVerified.ts.html @@ -23,9 +23,9 @@

All files / publisher
- 33.33% + 16.66% Statements - 2/6 + 1/6
@@ -37,16 +37,16 @@

All files / publisher
- 100% + 50% Functions - 2/2 + 1/2
- 33.33% + 16.66% Lines - 2/6 + 1/6
@@ -83,8 +83,8 @@

All files / publisher 18      -36x -2x +16x +        @@ -100,8 +100,8 @@

All files / publisher  
import { useQuery } from "react-query";
  
 function useVerified(snapName: string | undefined) {
-  return useQuery("verified", async () => {
-    const response = await fetch(`/api/${snapName}/verify`);
+  return useQuery("verified", async () => {
+    const response = await fetch(`/api/${snapName}/verify`);
  
     if (!response.ok) {
       throw new Error("There was a problem verifying this domain");
@@ -121,7 +121,7 @@ 

All files / publisher - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/sections/ContactInformationSection/index.ts.html b/coverage/js/publisher/listing/sections/ContactInformationSection/index.ts.html deleted file mode 100644 index c7fa68846..000000000 --- a/coverage/js/publisher/listing/sections/ContactInformationSection/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/sections/ContactInformationSection/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/sections/ContactInformationSection index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./ContactInformationSection";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/sections/ListingDetailsSection/index.ts.html b/coverage/js/publisher/listing/sections/ListingDetailsSection/index.ts.html deleted file mode 100644 index b31bebfd3..000000000 --- a/coverage/js/publisher/listing/sections/ListingDetailsSection/index.ts.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Code coverage report for publisher/listing/sections/ListingDetailsSection/index.ts - - - - - - - - - -
-
-

All files / publisher/listing/sections/ListingDetailsSection index.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 0/0 -
- - -
- 0% - Functions - 0/0 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2  - 
export { default } from "./ListingDetailsSection";
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/sections/ListingDetailsSection/index.html b/coverage/js/publisher/listing/test-utils/index.html similarity index 83% rename from coverage/js/publisher/listing/sections/ListingDetailsSection/index.html rename to coverage/js/publisher/listing/test-utils/index.html index 1e2fb6a38..9f7cc5b5c 100644 --- a/coverage/js/publisher/listing/sections/ListingDetailsSection/index.html +++ b/coverage/js/publisher/listing/test-utils/index.html @@ -3,15 +3,15 @@ - Code coverage report for publisher/listing/sections/ListingDetailsSection + Code coverage report for publisher/listing/test-utils - - - + + + @@ -19,7 +19,7 @@
-

All files publisher/listing/sections/ListingDetailsSection

+

All files publisher/listing/test-utils

@@ -39,7 +39,7 @@

All files publisher/listing/sections/Li
100% Functions - 1/1 + 0/0
@@ -79,21 +79,6 @@

All files publisher/listing/sections/Li - ListingDetailsSection.tsx - -
- - 100% - 1/1 - 100% - 0/0 - 100% - 1/1 - 100% - 1/1 - - - index.ts
@@ -108,6 +93,21 @@

All files publisher/listing/sections/Li 0/0 + + mockData.ts + +
+ + 100% + 1/1 + 100% + 0/0 + 100% + 0/0 + 100% + 1/1 + +

@@ -116,16 +116,16 @@

All files publisher/listing/sections/Li - + - - + + \ No newline at end of file diff --git a/coverage/js/publisher/shared/SaveStateNotifications/index.ts.html b/coverage/js/publisher/listing/test-utils/index.ts.html similarity index 84% rename from coverage/js/publisher/shared/SaveStateNotifications/index.ts.html rename to coverage/js/publisher/listing/test-utils/index.ts.html index e6043801f..433a71df1 100644 --- a/coverage/js/publisher/shared/SaveStateNotifications/index.ts.html +++ b/coverage/js/publisher/listing/test-utils/index.ts.html @@ -3,7 +3,7 @@ - Code coverage report for publisher/shared/SaveStateNotifications/index.ts + Code coverage report for publisher/listing/test-utils/index.ts @@ -19,7 +19,7 @@
-

All files / publisher/shared/SaveStateNotifications index.ts

+

All files / publisher/listing/test-utils index.ts

@@ -64,8 +64,14 @@

All files / publisher
1 -2  - 
export { default } from "./SaveStateNotifications";
+2
+3
+4
  +  +  + 
import { mockData } from "./mockData";
+ 
+export { mockData };
  
@@ -73,7 +79,7 @@

All files / publisher + - - + + \ No newline at end of file diff --git a/coverage/js/publisher/listing/utils/getChanges.ts.html b/coverage/js/publisher/listing/utils/getChanges.ts.html index 54d003780..6dc2b290a 100644 --- a/coverage/js/publisher/listing/utils/getChanges.ts.html +++ b/coverage/js/publisher/listing/utils/getChanges.ts.html @@ -23,30 +23,30 @@

All files / publisher

-
+
1 2 @@ -182,75 +182,18 @@

All files / publisher 117 118 119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150

2x +120            -1x   -1x -1x     -  -  -  -  -1x -1x -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -1x -1x -1x     +        @@ -258,258 +201,225 @@

All files / publisher       -  -1x -  -  +          -4x -4x -4x         +              -4x -8x     -4x       -4x +      -4x             +    +  +  +    -2x -2x   -1x +  +      -1x     -1x       +  +    -4x       -1x +  +    +  +      +  +      -4x +      +        +  +      -1x     +  +      +        -4x -17x -9x +      -17x -8x +    -8x -8x     -8x -8x +          -4x     +    - 

const formatImageChanges = (
-  bannerUrl: [string],
-  iconUrl: string,
-  screenshotUrls: [string],
-  screenshots: [FileList]
-) => {
-  const images = [];
+ 
import formatImageChanges from "./formatImageChanges";
  
-  Eif (bannerUrl) {
-    images.push({
-      url: bannerUrl,
-      type: "banner",
-      status: "uploaded",
-    });
-  }
- 
-  Eif (iconUrl) {
-    images.push({
-      url: iconUrl,
-      type: "icon",
-      status: "uploaded",
-    });
-  }
+import type { Data } from "../types";
  
-  Eif (screenshotUrls.length) {
-    screenshotUrls.forEach((url) => {
-      images.push({
-        url,
-        type: "screenshot",
-        status: "uploaded",
-      });
-    });
-  }
+export default function getChanges(
+  dirtyFields: any,
+  fieldValues: any,
+  data: Data
+): { [key: string]: any } {
+  const changes: { [key: string]: any } = {};
  
-  Eif (screenshots) {
-    screenshots.forEach((screenshot) => {
-      Iif (screenshot[0]) {
-        images.push({
-          url: URL.createObjectURL(screenshot[0]),
-          type: "screenshot",
-          status: "new",
-          name: screenshot[0].name,
-        });
-      }
-    });
+  if (
+    dirtyFields.banner_urls ||
+    dirtyFields.icon_url ||
+    dirtyFields.screenshot_urls ||
+    dirtyFields.icon ||
+    dirtyFields.banner ||
+    dirtyFields.screenshots
+  ) {
+    changes.images = formatImageChanges(
+      data.banner_urls,
+      fieldValues.icon_url,
+      fieldValues.screenshot_urls,
+      fieldValues.screenshots,
+      dirtyFields
+    );
   }
  
-  return images;
-};
- 
-function getChanges(
-  dirtyFields: { [key: string]: any },
-  data: { [key: string]: any }
-) {
-  const changes: { [key: string]: any } = {};
-  const keys = Object.keys(dirtyFields);
-  const forbiddenKeys = [
-    "primary-category",
-    "secondary-category",
+  const forbiddenKeys = [
+    "primary_category",
+    "secondary_category",
+    "websites",
     "contacts",
     "donations",
+    "source_code",
     "issues",
-    "source-code",
+    "icon",
+    "icon_url",
+  ];
+ 
+  const linksKeys = [
     "websites",
-    "licenses",
+    "contacts",
+    "donations",
+    "source_code",
+    "issues",
+    "primary_website",
   ];
  
-  const removeEmptyUrls = (urls: Array<{ url: string }>) => {
-    return urls.filter((url) => url.url !== "");
-  };
+  const getUrls = (item: { url: string }) => item.url;
+ 
+  for (const [key, value] of Object.entries(dirtyFields)) {
+    if (!forbiddenKeys.includes(key) && value !== false) {
+      changes[key] = fieldValues[key];
+    }
  
-  const combineWebsites = (
-    primaryWebsite: string,
-    websites: Array<{ url: string }>
-  ) => {
-    return [{ url: primaryWebsite }].concat(websites);
-  };
+    if (linksKeys.includes(key)) {
+      changes.links = {
+        contact: fieldValues.contacts.map(getUrls),
+        donations: fieldValues.donations.map(getUrls),
+        issues: fieldValues.issues.map(getUrls),
+        source: fieldValues.source_code.map(getUrls),
+        website: fieldValues.websites.map(getUrls),
+      };
  
-  if (
-    dirtyFields.primary_website ||
-    dirtyFields.contacts ||
-    dirtyFields.donations ||
-    dirtyFields.issues ||
-    dirtyFields.license ||
-    dirtyFields["source-code"] ||
-    dirtyFields.website
-  ) {
-    combineWebsites(data.primary_website, data.websites);
-    changes.links = {
-      contact: data.contacts
-        ? removeEmptyUrls(data.contacts).map((url: { url: string }) => url.url)
-        : [],
-      donations: data.donations
-        ? removeEmptyUrls(data.donations).map((url: { url: string }) => url.url)
-        : [],
-      issues: data.issues
-        ? removeEmptyUrls(data.issues).map((url: { url: string }) => url.url)
-        : [],
-      website: data.websites
-        ? removeEmptyUrls(
-            combineWebsites(data.primary_website, data.websites)
-          ).map((url: { url: string }) => url.url)
-        : [],
-      source: data["source-code"]
-        ? removeEmptyUrls(data["source-code"]).map(
-            (url: { url: string }) => url.url
-          )
-        : [],
-    };
+      if (fieldValues.primary_website) {
+        changes.links.website.unshift(fieldValues.primary_website);
+      }
+    }
   }
  
-  if (
-    dirtyFields.banner_url ||
-    dirtyFields.icon_url ||
-    dirtyFields.screenshot_urls ||
-    dirtyFields.icon ||
-    dirtyFields.banner ||
-    dirtyFields.screenshots
-  ) {
-    changes.images = formatImageChanges(
-      data?.banner_url,
-      data?.icon_url,
-      data?.screenshot_urls,
-      data?.screenshots
-    );
+  if (dirtyFields.primary_category || dirtyFields.secondary_category) {
+    const categories = [];
+ 
+    if (fieldValues.primary_category) {
+      categories.push(fieldValues.primary_category);
+    }
+ 
+    if (fieldValues.secondary_category) {
+      categories.push(fieldValues.secondary_category);
+    }
+ 
+    changes.categories = categories;
   }
  
-  keys.forEach((key) => {
-    if (!forbiddenKeys.includes(key) && dirtyFields[key] === true) {
-      changes[key] = data[key];
+  if (
+    dirtyFields.public_metrics_territories ||
+    dirtyFields.public_metrics_distros
+  ) {
+    if (fieldValues.public_metrics_territories === true) {
+      changes.public_metrics_blacklist = [
+        "weekly_installed_base_by_operating_system_normalized",
+      ];
     }
  
-    if (dirtyFields["primary-category"] || dirtyFields["secondary-category"]) {
-      changes.categories = [];
+    if (fieldValues.public_metrics_distros === true) {
+      changes.public_metrics_blacklist = ["installed_base_by_country_percent"];
+    }
  
-      Eif (data["primary-category"]) {
-        changes.categories.push(data["primary-category"]);
-      }
+    if (
+      fieldValues.public_metrics_territories === true &&
+      fieldValues.public_metrics_distros === true
+    ) {
+      changes.public_metrics_blacklist = [];
+    }
  
-      Eif (data["secondary-category"]) {
-        changes.categories.push(data["secondary-category"]);
-      }
+    if (
+      fieldValues.public_metrics_territories === false &&
+      fieldValues.public_metrics_distros === false
+    ) {
+      changes.public_metrics_blacklist = [
+        "installed_base_by_country_percent",
+        "weekly_installed_base_by_operating_system_normalized",
+      ];
     }
-  });
+  }
  
-  return changes;
+  return changes;
 }
- 
-export default getChanges;
  
@@ -517,7 +427,7 @@

All files / publisher + - - + + \ No newline at end of file diff --git a/coverage/js/publisher/listing/utils/getFormData.ts.html b/coverage/js/publisher/listing/utils/getFormData.ts.html deleted file mode 100644 index 7cf5fa379..000000000 --- a/coverage/js/publisher/listing/utils/getFormData.ts.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - Code coverage report for publisher/listing/utils/getFormData.ts - - - - - - - - - -
-
-

All files / publisher/listing/utils getFormData.ts

-
- -
- 77.35% - Statements - 41/53 -
- - -
- 50% - Branches - 18/36 -
- - -
- 66.66% - Functions - 4/6 -
- - -
- 76.92% - Lines - 40/52 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -1162x -  -  -  -  -  -  -  -2x -5x -  -  -  -  -  -  -  -1x -  -1x -1x -  -1x -1x -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -  -  -  -1x -1x -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  - 
const addDateToFilename = (file: File): File => {
-  const now = Math.round(new Date().getTime() / 1000);
-  const nameParts = file.name.split(".");
-  const extension = nameParts.pop();
-  const newName = `${nameParts.join(".")}-${now}.${extension}`;
-  return new File([file], newName);
-};
- 
-const formatLinkFields = (fields: Array<{ url: string }>) => {
-  return fields.map((item) => item.url);
-};
- 
-function getFormData(
-  data: { [key: string]: any },
-  snapId: string | undefined,
-  changes: { [key: string]: any }
-) {
-  const formData = new FormData();
- 
-  formData.set("csrf_token", window.CSRF_TOKEN);
-  formData.set("snap_id", snapId || "");
- 
-  Eif (changes.title) {
-    formData.set("title", data?.title);
-  }
- 
-  Eif (changes.summary) {
-    formData.set("summary", data?.summary);
-  }
- 
-  Eif (changes.description) {
-    formData.set("description", data?.description);
-  }
- 
-  Eif (changes.video_urls) {
-    formData.set("video_urls", data?.video_urls);
-  }
- 
-  Eif (changes.website) {
-    formData.set("website", data?.website);
-  }
- 
-  Eif (changes.contact) {
-    formData.set("contact", data?.contact);
-  }
- 
-  Eif (changes.categories) {
-    formData.set("primary-category", data?.["primary-category"]);
-    formData.set("secondary-category", data?.["secondary-category"]);
-  }
- 
-  Eif (changes.public_metrics_enabled) {
-    formData.set("public_metrics_enabled", data?.public_metrics_enabled);
-  }
- 
-  Eif (changes.public_metrics_blacklist) {
-    formData.set("public_metrics_blacklist", data?.public_metrics_blacklist);
-  }
- 
-  Eif (changes.license) {
-    formData.set("license", data?.license || "unset");
-  }
- 
-  // The currently uploaded images
-  Eif (changes.images) {
-    formData.set("images", data?.["images"]);
-  }
- 
-  Eif (changes.links) {
-    formData.set(
-      "links",
-      JSON.stringify({
-        contact: formatLinkFields(data?.contacts),
-        donation: formatLinkFields(data?.donations),
-        issues: formatLinkFields(data?.issues),
-        "source-code": formatLinkFields(data?.["source-code"]),
-        website: formatLinkFields(data?.websites),
-      })
-    );
-  }
- 
-  Eif (data?.icon?.[0]) {
-    formData.append("icon", data.icon[0]);
-  }
- 
-  Eif (data?.banner?.[0]) {
-    formData.append("banner-image", data.banner[0]);
-  }
- 
-  Eif (data?.screenshots) {
-    data?.screenshots.forEach((screenshot: FileList) => {
-      Iif (screenshot[0]) {
-        // Add a timestamp to the filename
-        const oldName = screenshot[0].name;
-        const newFile = addDateToFilename(screenshot[0]);
- 
-        formData.append("screenshots", newFile);
- 
-        // update changes object
-        const imageIndex = changes.images.findIndex(
-          (image: any) => image.name === oldName
-        );
-        changes.images[imageIndex].name = newFile.name;
-        changes.images[imageIndex].url = URL.createObjectURL(newFile);
-      }
-    });
-  }
- 
-  // Set changes last, just incase any modifications have happened
-  formData.set("changes", JSON.stringify(changes));
- 
-  return formData;
-}
- 
-export default getFormData;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/utils/getListingData.ts.html b/coverage/js/publisher/listing/utils/getListingData.ts.html deleted file mode 100644 index bd3e6c192..000000000 --- a/coverage/js/publisher/listing/utils/getListingData.ts.html +++ /dev/null @@ -1,508 +0,0 @@ - - - - - - Code coverage report for publisher/listing/utils/getListingData.ts - - - - - - - - - -
-
-

All files / publisher/listing/utils getListingData.ts

-
- -
- 95.83% - Statements - 23/24 -
- - -
- 86.84% - Branches - 33/38 -
- - -
- 100% - Functions - 9/9 -
- - -
- 95.65% - Lines - 22/23 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142  -  -  -  -  -2x -27x -27x -  -  -  -  -  -  -  -2x -12421x -1x -  -  -12420x -12069x -  -  -351x -  -  -  -28x -  -28x -28x -  -  -  -  -  -  -28x -28x -  -  -  -  -  -  -28x -28x -  -136x -  -  -  -  -  -  -  -  -28x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -27x -  -  -  -  -  -  -  -27x -  -  -  -  -  -  -  -27x -  -  -  -  -  -  -  -27x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
type License = {
-  key: string;
-  name: string;
-};
- 
-const getOtherWebsites = (websites: Array<string>) => {
-  Eif (websites.length > 1) {
-    return websites.slice(1, websites.length).map((url) => ({ url })) as Array<{
-      url: string;
-    }>;
-  }
- 
-  return [] as [];
-};
- 
-const licenseSort = (a: License, b: License) => {
-  if (a.name < b.name) {
-    return -1;
-  }
- 
-  if (a.name > b.name) {
-    return 1;
-  }
- 
-  return 0;
-};
- 
-function getListingData(listingData: { [key: string]: any }) {
-  let images = [];
- 
-  Eif (window?.listingData?.icon_url) {
-    images.push({
-      url: window?.listingData?.icon_url,
-      type: "icon",
-      status: "uploaded",
-    });
-  }
- 
-  Eif (window?.listingData?.banner_urls.length) {
-    images.push({
-      url: window?.listingData?.banner_urls[0],
-      type: "banner",
-      status: "uploaded",
-    });
-  }
- 
-  Eif (window?.listingData?.screenshot_urls) {
-    images = images.concat(
-      window?.listingData?.screenshot_urls.map((url: string) => {
-        return {
-          url,
-          type: "screenshot",
-          status: "uploaded",
-        };
-      })
-    );
-  }
- 
-  return {
-    snap_name: listingData?.snap_name,
-    title: listingData?.snap_title,
-    summary: listingData?.summary,
-    description: listingData?.description,
-    website: listingData?.website,
-    contact: listingData?.contact,
-    categories: listingData?.categories,
-    public_metrics_enabled: listingData?.public_metrics_enabled,
-    public_metrics_blacklist: listingData?.public_metrics_blacklist,
-    license: listingData?.license,
-    license_type: listingData?.license_type,
-    licenses: listingData?.licenses.sort(licenseSort),
-    video_urls: listingData?.video_urls[0] || "",
-    "primary-category": listingData?.snap_categories?.categories[0],
-    "secondary-category": listingData?.snap_categories?.categories[1],
-    public_metrics_territories: !listingData?.public_metrics_blacklist.includes(
-      "installed_base_by_country_percent"
-    ),
-    public_metrics_distros: !listingData?.public_metrics_blacklist.includes(
-      "weekly_installed_base_by_operating_system_normalized"
-    ),
-    update_metadata_on_release: listingData?.update_metadata_on_release,
-    contacts:
-      listingData.links && listingData.links.contact
-        ? listingData.links.contact.map((link: string) => {
-            return {
-              url: link,
-            };
-          })
-        : [],
-    donations:
-      listingData.links && listingData.links.donations
-        ? listingData.links.donations.map((link: string) => {
-            return {
-              url: link,
-            };
-          })
-        : [],
-    issues:
-      listingData.links && listingData.links.issues
-        ? listingData.links.issues.map((link: string) => {
-            return {
-              url: link,
-            };
-          })
-        : [],
-    "source-code":
-      listingData.links && listingData.links["source"]
-        ? listingData.links["source"].map((link: string) => {
-            return {
-              url: link,
-            };
-          })
-        : [],
-    primary_website:
-      listingData.links && listingData.links.website
-        ? listingData.links.website[0]
-        : "",
-    websites:
-      listingData.links && listingData.links.website
-        ? getOtherWebsites(listingData.links.website)
-        : [],
-    banner_urls: window?.listingData?.banner_urls,
-    icon_url: window?.listingData?.icon_url,
-    screenshot_urls: window?.listingData?.screenshot_urls,
-    icon: new File([], ""),
-    banner_url: window?.listingData?.banner_urls[0],
-    banner: new File([], ""),
-    screenshots: [
-      new File([], ""),
-      new File([], ""),
-      new File([], ""),
-      new File([], ""),
-      new File([], ""),
-    ],
-    images,
-    snap_categories: window?.listingData?.snap_categories?.categories,
-    links: window?.listingData?.links,
-  };
-}
- 
-export default getListingData;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/utils/index.html b/coverage/js/publisher/listing/utils/index.html index c16f32bfa..7d4d9698b 100644 --- a/coverage/js/publisher/listing/utils/index.html +++ b/coverage/js/publisher/listing/utils/index.html @@ -23,30 +23,30 @@

All files publisher/listing/utils

- 90.2% + 51.94% Statements - 129/143 + 40/77
- 76.33% + 44.44% Branches - 129/169 + 40/90
- 94.11% + 75% Functions - 32/34 + 9/12
- 90% + 52.63% Lines - 126/140 + 40/76
@@ -61,7 +61,7 @@

All files publisher/listing/utils

-
+
@@ -79,78 +79,63 @@

All files publisher/listing/utils

- + - + - + - + - - + - - - - - - - - - - - - - - - + + - - - - - + + + + + - - + - - - - - - - - + + + + + + + + - - + - - - - + + + + - - - + + + @@ -183,21 +168,6 @@

All files publisher/listing/utils

- - - - - - - - - - - - -
formatFileSize.tsaddDateToFilename.ts
100%3/35/5 100%2/20/0 100% 1/1 100%3/35/5
getChanges.ts -
+
formatImageChanges.ts +
97.61%41/4283.67%41/49100%13/1397.56%40/41
getDefaultValues.ts -
-
100%1/184.61%11/13 50%9/18100%1/1100%1/16/1266.66%2/384.61%11/13
getFormData.ts -
+
getChanges.ts +
77.35%41/5350%18/3666.66%4/676.92%40/520%0/310%0/400%0/20%0/30
getListingData.ts -
+
getDefaultData.ts +
95.83%23/2486.84%33/3863.63%7/1166.66%8/12 100%9/995.65%22/233/363.63%7/11
16/16
validateAspectRatio.ts -
-
100%3/3100%0/0100%1/1100%3/3
validateImageDimensions.ts @@ -221,7 +191,7 @@

All files publisher/listing/utils

- - - - - - \ No newline at end of file diff --git a/coverage/js/publisher/listing/utils/validateImageDimensions.ts.html b/coverage/js/publisher/listing/utils/validateImageDimensions.ts.html index ddcf1d15e..594eaf23e 100644 --- a/coverage/js/publisher/listing/utils/validateImageDimensions.ts.html +++ b/coverage/js/publisher/listing/utils/validateImageDimensions.ts.html @@ -127,7 +127,7 @@

All files / publisher @@ -18,13 +18,13 @@ diff --git a/coverage/python/tests_publisher_snaps___init___py.html b/coverage/python/tests_publisher_snaps___init___py.html index bbbaa801c..ac0af0147 100644 --- a/coverage/python/tests_publisher_snaps___init___py.html +++ b/coverage/python/tests_publisher_snaps___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_test_builds_py.html b/coverage/python/tests_publisher_snaps_test_builds_py.html index 5212558db..c1eb204cc 100644 --- a/coverage/python/tests_publisher_snaps_test_builds_py.html +++ b/coverage/python/tests_publisher_snaps_test_builds_py.html @@ -174,7 +174,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_test_logic_py.html b/coverage/python/tests_publisher_snaps_test_logic_py.html index 10528d651..4025fc2f9 100644 --- a/coverage/python/tests_publisher_snaps_test_logic_py.html +++ b/coverage/python/tests_publisher_snaps_test_logic_py.html @@ -101,7 +101,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_test_post_preview_py.html b/coverage/python/tests_publisher_snaps_test_post_preview_py.html index 56aa353f3..cff9563fe 100644 --- a/coverage/python/tests_publisher_snaps_test_post_preview_py.html +++ b/coverage/python/tests_publisher_snaps_test_post_preview_py.html @@ -127,7 +127,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_test_release_history_json_py.html b/coverage/python/tests_publisher_snaps_test_release_history_json_py.html index 5235e5118..78d9258aa 100644 --- a/coverage/python/tests_publisher_snaps_test_release_history_json_py.html +++ b/coverage/python/tests_publisher_snaps_test_release_history_json_py.html @@ -117,7 +117,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_get_metrics_py.html b/coverage/python/tests_publisher_snaps_tests_get_metrics_py.html index 0f155bc92..040f29ee1 100644 --- a/coverage/python/tests_publisher_snaps_tests_get_metrics_py.html +++ b/coverage/python/tests_publisher_snaps_tests_get_metrics_py.html @@ -586,7 +586,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_listing_py.html b/coverage/python/tests_publisher_snaps_tests_listing_py.html index 009fd5a69..a6c9a5634 100644 --- a/coverage/python/tests_publisher_snaps_tests_listing_py.html +++ b/coverage/python/tests_publisher_snaps_tests_listing_py.html @@ -22,8 +22,8 @@

Coverage for tests/publisher/snaps/tests_listing.py :

Show keyboard shortcuts

- 100 statements   - + 72 statements   +

@@ -59,7 +59,7 @@

5class ListingPageNotAuth(BaseTestCases.EndpointLoggedOut): 

6 def setUp(self): 

7 snap_name = "test-snap" 

-

8 endpoint_url = "/{}/listing".format(snap_name) 

+

8 endpoint_url = "/api/{}/listing".format(snap_name) 

9 

10 super().setUp(snap_name=snap_name, endpoint_url=endpoint_url) 

11 

@@ -70,7 +70,7 @@

16 

17 api_url = "https://dashboard.snapcraft.io/dev/api/snaps/info/{}" 

18 api_url = api_url.format(snap_name) 

-

19 endpoint_url = "/{}/listing".format(snap_name) 

+

19 endpoint_url = "/api/{}/listing".format(snap_name) 

20 

21 super().setUp( 

22 snap_name=snap_name, 

@@ -115,7 +115,7 @@

61 "categories": {"items": []}, 

62 "status": "published", 

63 "update_metadata_on_release": True, 

-

64 "links": {"website": "https://example.com"}, 

+

64 "links": {"website": ["https://example.com"]}, 

65 } 

66 

67 responses.add(responses.GET, self.api_url, json=payload, status=200) 

@@ -133,242 +133,208 @@

79 self.check_call_by_api_url(responses.calls) 

80 

81 assert response.status_code == 200 

-

82 self.assert_template_used("publisher/listing.html") 

-

83 

-

84 self.assert_context("snap_id", "id") 

-

85 self.assert_context("snap_name", snap_name) 

-

86 self.assert_context("snap_title", "Snap title") 

-

87 self.assert_context("summary", "This is a summary") 

-

88 self.assert_context("description", "This is a description") 

-

89 self.assert_context("icon_url", None) 

-

90 self.assert_context("publisher_name", "The publisher") 

-

91 self.assert_context("username", "toto") 

-

92 self.assert_context("screenshot_urls", []) 

-

93 self.assert_context("contact", "contact adress") 

-

94 self.assert_context("website", "website_url") 

-

95 self.assert_context("is_on_stable", False) 

-

96 self.assert_context("public_metrics_enabled", True) 

-

97 self.assert_context("public_metrics_blacklist", False) 

-

98 self.assert_context("license", "License") 

-

99 self.assert_context("video_urls", []) 

-

100 self.assert_context("from", "test") 

-

101 

-

102 @responses.activate 

-

103 def test_icon(self): 

-

104 payload = { 

-

105 "snap_id": "id", 

-

106 "snap_name": self.snap_name, 

-

107 "title": "Snap title", 

-

108 "summary": "This is a summary", 

-

109 "description": "This is a description", 

-

110 "media": [{"url": "this is a url", "type": "icon"}], 

-

111 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

112 "private": True, 

-

113 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

114 "contact": "contact adress", 

-

115 "website": "website_url", 

-

116 "public_metrics_enabled": True, 

-

117 "public_metrics_blacklist": True, 

-

118 "license": "license", 

-

119 "video_urls": [], 

-

120 "categories": {"items": []}, 

-

121 "status": "published", 

-

122 "update_metadata_on_release": True, 

-

123 "links": {"website": "https://example.com"}, 

-

124 } 

-

125 

-

126 responses.add(responses.GET, self.api_url, json=payload, status=200) 

-

127 responses.add( 

-

128 responses.GET, 

-

129 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

130 json=[], 

-

131 status=200, 

-

132 ) 

-

133 

-

134 response = self.client.get(self.endpoint_url) 

-

135 

-

136 self.check_call_by_api_url(responses.calls) 

-

137 

-

138 assert response.status_code == 200 

-

139 self.assert_template_used("publisher/listing.html") 

-

140 

-

141 self.assert_context("icon_url", "this is a url") 

-

142 

-

143 @responses.activate 

-

144 def test_screenshots(self): 

-

145 payload = { 

-

146 "snap_id": "id", 

-

147 "snap_name": self.snap_name, 

-

148 "title": "Snap title", 

-

149 "summary": "This is a summary", 

-

150 "description": "This is a description", 

-

151 "media": [{"url": "this is a url", "type": "screenshot"}], 

-

152 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

153 "private": True, 

-

154 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

155 "contact": "contact adress", 

-

156 "website": "website_url", 

-

157 "public_metrics_enabled": True, 

-

158 "public_metrics_blacklist": True, 

-

159 "license": "license", 

-

160 "video_urls": [], 

-

161 "categories": {"items": []}, 

-

162 "status": "published", 

-

163 "update_metadata_on_release": True, 

-

164 "links": {"website": "https://example.com"}, 

-

165 } 

-

166 

-

167 responses.add(responses.GET, self.api_url, json=payload, status=200) 

-

168 responses.add( 

-

169 responses.GET, 

-

170 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

171 json=[], 

-

172 status=200, 

-

173 ) 

-

174 

-

175 response = self.client.get(self.endpoint_url) 

-

176 

-

177 self.check_call_by_api_url(responses.calls) 

-

178 

-

179 assert response.status_code == 200 

-

180 self.assert_template_used("publisher/listing.html") 

-

181 

-

182 self.assert_context("screenshot_urls", ["this is a url"]) 

-

183 

-

184 @responses.activate 

-

185 def test_banner_images(self): 

-

186 payload = { 

-

187 "snap_id": "id", 

-

188 "snap_name": self.snap_name, 

-

189 "title": "Snap title", 

-

190 "summary": "This is a summary", 

-

191 "description": "This is a description", 

-

192 "media": [ 

-

193 {"url": "/banner_1234.png", "type": "banner"}, 

-

194 {"url": "/test.jpg", "type": "screenshot"}, 

-

195 {"url": "/banner-icon_4321.jpg", "type": "screenshot"}, 

-

196 {"url": "/banner-test.png", "type": "screenshot"}, 

-

197 {"url": "/banner-icon", "type": "screenshot"}, 

-

198 ], 

-

199 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

200 "private": True, 

-

201 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

202 "contact": "contact adress", 

-

203 "website": "website_url", 

-

204 "public_metrics_enabled": True, 

-

205 "public_metrics_blacklist": True, 

-

206 "license": "license", 

-

207 "video_urls": [], 

-

208 "categories": {"items": []}, 

-

209 "status": "published", 

-

210 "update_metadata_on_release": True, 

-

211 "links": {"website": "https://example.com"}, 

-

212 } 

-

213 

-

214 responses.add(responses.GET, self.api_url, json=payload, status=200) 

-

215 responses.add( 

-

216 responses.GET, 

-

217 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

218 json=[], 

-

219 status=200, 

-

220 ) 

-

221 

-

222 response = self.client.get(self.endpoint_url) 

-

223 

-

224 self.check_call_by_api_url(responses.calls) 

-

225 

-

226 assert response.status_code == 200 

-

227 self.assert_template_used("publisher/listing.html") 

-

228 

-

229 self.assert_context("banner_urls", ["/banner_1234.png"]) 

-

230 

-

231 @responses.activate 

-

232 def test_videos(self): 

-

233 payload = { 

-

234 "snap_id": "id", 

-

235 "snap_name": self.snap_name, 

-

236 "title": "Snap title", 

-

237 "summary": "This is a summary", 

-

238 "description": "This is a description", 

-

239 "media": [], 

-

240 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

241 "private": True, 

-

242 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

243 "contact": "contact adress", 

-

244 "website": "website_url", 

-

245 "public_metrics_enabled": True, 

-

246 "public_metrics_blacklist": True, 

-

247 "license": "license", 

-

248 "video_urls": ["https://youtube.com/watch?v=1234"], 

-

249 "categories": {"items": []}, 

-

250 "status": "published", 

-

251 "update_metadata_on_release": True, 

-

252 "links": {"website": "https://example.com"}, 

-

253 } 

-

254 

-

255 responses.add(responses.GET, self.api_url, json=payload, status=200) 

-

256 responses.add( 

-

257 responses.GET, 

-

258 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

259 json=[], 

-

260 status=200, 

-

261 ) 

-

262 

-

263 response = self.client.get(self.endpoint_url) 

+

82 

+

83 @responses.activate 

+

84 def test_icon(self): 

+

85 payload = { 

+

86 "snap_id": "id", 

+

87 "snap_name": self.snap_name, 

+

88 "title": "Snap title", 

+

89 "summary": "This is a summary", 

+

90 "description": "This is a description", 

+

91 "media": [{"url": "this is a url", "type": "icon"}], 

+

92 "publisher": {"display-name": "The publisher", "username": "toto"}, 

+

93 "private": True, 

+

94 "channel_maps_list": [{"map": [{"info": "info"}]}], 

+

95 "contact": "contact adress", 

+

96 "website": "website_url", 

+

97 "public_metrics_enabled": True, 

+

98 "public_metrics_blacklist": True, 

+

99 "license": "license", 

+

100 "video_urls": [], 

+

101 "categories": {"items": []}, 

+

102 "status": "published", 

+

103 "update_metadata_on_release": True, 

+

104 "links": {"website": ["https://example.com"]}, 

+

105 } 

+

106 

+

107 responses.add(responses.GET, self.api_url, json=payload, status=200) 

+

108 responses.add( 

+

109 responses.GET, 

+

110 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

+

111 json=[], 

+

112 status=200, 

+

113 ) 

+

114 

+

115 response = self.client.get(self.endpoint_url) 

+

116 

+

117 self.check_call_by_api_url(responses.calls) 

+

118 

+

119 assert response.status_code == 200 

+

120 

+

121 @responses.activate 

+

122 def test_screenshots(self): 

+

123 payload = { 

+

124 "snap_id": "id", 

+

125 "snap_name": self.snap_name, 

+

126 "title": "Snap title", 

+

127 "summary": "This is a summary", 

+

128 "description": "This is a description", 

+

129 "media": [{"url": "this is a url", "type": "screenshot"}], 

+

130 "publisher": {"display-name": "The publisher", "username": "toto"}, 

+

131 "private": True, 

+

132 "channel_maps_list": [{"map": [{"info": "info"}]}], 

+

133 "contact": "contact adress", 

+

134 "website": "website_url", 

+

135 "public_metrics_enabled": True, 

+

136 "public_metrics_blacklist": True, 

+

137 "license": "license", 

+

138 "video_urls": [], 

+

139 "categories": {"items": []}, 

+

140 "status": "published", 

+

141 "update_metadata_on_release": True, 

+

142 "links": {"website": ["https://example.com"]}, 

+

143 } 

+

144 

+

145 responses.add(responses.GET, self.api_url, json=payload, status=200) 

+

146 responses.add( 

+

147 responses.GET, 

+

148 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

+

149 json=[], 

+

150 status=200, 

+

151 ) 

+

152 

+

153 response = self.client.get(self.endpoint_url) 

+

154 

+

155 self.check_call_by_api_url(responses.calls) 

+

156 

+

157 assert response.status_code == 200 

+

158 

+

159 @responses.activate 

+

160 def test_banner_images(self): 

+

161 payload = { 

+

162 "snap_id": "id", 

+

163 "snap_name": self.snap_name, 

+

164 "title": "Snap title", 

+

165 "summary": "This is a summary", 

+

166 "description": "This is a description", 

+

167 "media": [ 

+

168 {"url": "/banner_1234.png", "type": "banner"}, 

+

169 {"url": "/test.jpg", "type": "screenshot"}, 

+

170 {"url": "/banner-icon_4321.jpg", "type": "screenshot"}, 

+

171 {"url": "/banner-test.png", "type": "screenshot"}, 

+

172 {"url": "/banner-icon", "type": "screenshot"}, 

+

173 ], 

+

174 "publisher": {"display-name": "The publisher", "username": "toto"}, 

+

175 "private": True, 

+

176 "channel_maps_list": [{"map": [{"info": "info"}]}], 

+

177 "contact": "contact adress", 

+

178 "website": "website_url", 

+

179 "public_metrics_enabled": True, 

+

180 "public_metrics_blacklist": True, 

+

181 "license": "license", 

+

182 "video_urls": [], 

+

183 "categories": {"items": []}, 

+

184 "status": "published", 

+

185 "update_metadata_on_release": True, 

+

186 "links": {"website": ["https://example.com"]}, 

+

187 } 

+

188 

+

189 responses.add(responses.GET, self.api_url, json=payload, status=200) 

+

190 responses.add( 

+

191 responses.GET, 

+

192 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

+

193 json=[], 

+

194 status=200, 

+

195 ) 

+

196 

+

197 response = self.client.get(self.endpoint_url) 

+

198 

+

199 self.check_call_by_api_url(responses.calls) 

+

200 

+

201 assert response.status_code == 200 

+

202 

+

203 @responses.activate 

+

204 def test_videos(self): 

+

205 payload = { 

+

206 "snap_id": "id", 

+

207 "snap_name": self.snap_name, 

+

208 "title": "Snap title", 

+

209 "summary": "This is a summary", 

+

210 "description": "This is a description", 

+

211 "media": [], 

+

212 "publisher": {"display-name": "The publisher", "username": "toto"}, 

+

213 "private": True, 

+

214 "channel_maps_list": [{"map": [{"info": "info"}]}], 

+

215 "contact": "contact adress", 

+

216 "website": "website_url", 

+

217 "public_metrics_enabled": True, 

+

218 "public_metrics_blacklist": True, 

+

219 "license": "license", 

+

220 "video_urls": ["https://youtube.com/watch?v=1234"], 

+

221 "categories": {"items": []}, 

+

222 "status": "published", 

+

223 "update_metadata_on_release": True, 

+

224 "links": {"website": ["https://example.com"]}, 

+

225 } 

+

226 

+

227 responses.add(responses.GET, self.api_url, json=payload, status=200) 

+

228 responses.add( 

+

229 responses.GET, 

+

230 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

+

231 json=[], 

+

232 status=200, 

+

233 ) 

+

234 

+

235 response = self.client.get(self.endpoint_url) 

+

236 

+

237 self.check_call_by_api_url(responses.calls) 

+

238 

+

239 assert response.status_code == 200 

+

240 

+

241 @responses.activate 

+

242 def test_failed_categories_api(self): 

+

243 payload = { 

+

244 "snap_id": "id", 

+

245 "snap_name": self.snap_name, 

+

246 "title": "Snap title", 

+

247 "summary": "This is a summary", 

+

248 "description": "This is a description", 

+

249 "media": [], 

+

250 "publisher": {"display-name": "The publisher", "username": "toto"}, 

+

251 "private": True, 

+

252 "channel_maps_list": [{"map": [{"info": "info"}]}], 

+

253 "contact": "contact adress", 

+

254 "website": "website_url", 

+

255 "public_metrics_enabled": True, 

+

256 "public_metrics_blacklist": True, 

+

257 "license": "license", 

+

258 "video_urls": ["https://youtube.com/watch?v=1234"], 

+

259 "categories": {"items": []}, 

+

260 "status": "published", 

+

261 "update_metadata_on_release": True, 

+

262 "links": {"website": ["https://example.com"]}, 

+

263 } 

264 

-

265 self.check_call_by_api_url(responses.calls) 

-

266 

-

267 assert response.status_code == 200 

-

268 self.assert_template_used("publisher/listing.html") 

-

269 

-

270 self.assert_context("video_urls", ["https://youtube.com/watch?v=1234"]) 

-

271 

-

272 @responses.activate 

-

273 def test_failed_categories_api(self): 

-

274 payload = { 

-

275 "snap_id": "id", 

-

276 "snap_name": self.snap_name, 

-

277 "title": "Snap title", 

-

278 "summary": "This is a summary", 

-

279 "description": "This is a description", 

-

280 "media": [], 

-

281 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

282 "private": True, 

-

283 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

284 "contact": "contact adress", 

-

285 "website": "website_url", 

-

286 "public_metrics_enabled": True, 

-

287 "public_metrics_blacklist": True, 

-

288 "license": "license", 

-

289 "video_urls": ["https://youtube.com/watch?v=1234"], 

-

290 "categories": {"items": []}, 

-

291 "status": "published", 

-

292 "update_metadata_on_release": True, 

-

293 "links": {"website": "https://example.com"}, 

-

294 } 

-

295 

-

296 responses.add(responses.GET, self.api_url, json=payload, status=200) 

-

297 responses.add( 

-

298 responses.GET, 

-

299 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

300 json=[], 

-

301 status=500, 

-

302 ) 

-

303 

-

304 response = self.client.get(self.endpoint_url) 

-

305 

-

306 self.check_call_by_api_url(responses.calls) 

-

307 

-

308 assert response.status_code == 200 

-

309 self.assert_template_used("publisher/listing.html") 

-

310 

-

311 self.assert_context("categories", []) 

+

265 responses.add(responses.GET, self.api_url, json=payload, status=200) 

+

266 responses.add( 

+

267 responses.GET, 

+

268 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

+

269 json=[], 

+

270 status=500, 

+

271 ) 

+

272 

+

273 response = self.client.get(self.endpoint_url) 

+

274 

+

275 self.check_call_by_api_url(responses.calls) 

+

276 

+

277 assert response.status_code == 200 

diff --git a/coverage/python/tests_publisher_snaps_tests_post_binary_metadata_py.html b/coverage/python/tests_publisher_snaps_tests_post_binary_metadata_py.html deleted file mode 100644 index 39c1157c5..000000000 --- a/coverage/python/tests_publisher_snaps_tests_post_binary_metadata_py.html +++ /dev/null @@ -1,519 +0,0 @@ - - - - - - Coverage for tests/publisher/snaps/tests_post_binary_metadata.py: 100% - - - - - - - - - - -
- Hide keyboard shortcuts -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
-
-

1import io 

-

2import json 

-

3 

-

4import responses 

-

5from tests.publisher.endpoint_testing import BaseTestCases 

-

6 

-

7 

-

8class PostBinaryMetadataListingPageLoggedOut(BaseTestCases.EndpointLoggedOut): 

-

9 def setUp(self): 

-

10 snap_name = "test-snap" 

-

11 endpoint_url = "/{}/listing".format(snap_name) 

-

12 

-

13 super().setUp( 

-

14 snap_name=snap_name, 

-

15 endpoint_url=endpoint_url, 

-

16 method_endpoint="POST", 

-

17 ) 

-

18 

-

19 

-

20class PostMetadataListingPage(BaseTestCases.EndpointLoggedInErrorHandling): 

-

21 def setUp(self): 

-

22 self.snap_id = "complexId" 

-

23 snap_name = "test-snap" 

-

24 endpoint_url = "/{}/listing".format(snap_name) 

-

25 api_url = ( 

-

26 "https://dashboard.snapcraft.io/dev/api/" 

-

27 "snaps/{}/binary-metadata?conflict_on_update=true" 

-

28 ).format(self.snap_id) 

-

29 

-

30 changes = {"images": None} 

-

31 data = dict(snap_id=self.snap_id, changes=json.dumps(changes)) 

-

32 

-

33 super().setUp( 

-

34 snap_name=snap_name, 

-

35 endpoint_url=endpoint_url, 

-

36 method_endpoint="POST", 

-

37 api_url=api_url, 

-

38 method_api="GET", 

-

39 data=data, 

-

40 ) 

-

41 

-

42 

-

43class PostBinaryMetadataErrorListingPage(BaseTestCases.EndpointLoggedIn): 

-

44 def setUp(self): 

-

45 responses.reset() 

-

46 

-

47 self.snap_id = "complexId" 

-

48 snap_name = "test-snap" 

-

49 endpoint_url = "/{}/listing".format(snap_name) 

-

50 binary_url = ( 

-

51 "https://dashboard.snapcraft.io/dev/api/" 

-

52 "snaps/{}/binary-metadata?conflict_on_update=true" 

-

53 ).format(self.snap_id) 

-

54 

-

55 responses.add(responses.GET, binary_url, json=[], status=200) 

-

56 payload = { 

-

57 "error_list": [ 

-

58 {"code": "this-is-a-code", "message": "Great error message"} 

-

59 ] 

-

60 } 

-

61 responses.add(responses.PUT, binary_url, json=payload, status=400) 

-

62 

-

63 api_url = "https://dashboard.snapcraft.io/dev/api/snaps/info/{}" 

-

64 api_url = api_url.format(snap_name) 

-

65 

-

66 changes = { 

-

67 "images": [ 

-

68 { 

-

69 "file": {}, 

-

70 "url": "blob:this_is_a_blob", 

-

71 "name": "blue.png", 

-

72 "type": "icon", 

-

73 "status": "new", 

-

74 } 

-

75 ] 

-

76 } 

-

77 

-

78 data = dict( 

-

79 icon=[(io.BytesIO(b"my file contents"), "blue.png")], 

-

80 snap_id=self.snap_id, 

-

81 changes=json.dumps(changes), 

-

82 ) 

-

83 

-

84 super().setUp( 

-

85 snap_name=snap_name, 

-

86 endpoint_url=endpoint_url, 

-

87 method_endpoint="POST", 

-

88 api_url=api_url, 

-

89 method_api="GET", 

-

90 data=data, 

-

91 ) 

-

92 

-

93 

-

94class PostBinaryMetadataListingPage(BaseTestCases.EndpointLoggedIn): 

-

95 def setUp(self): 

-

96 responses.reset() 

-

97 

-

98 self.snap_id = "complexId" 

-

99 snap_name = "test-snap" 

-

100 endpoint_url = "/{}/listing".format(snap_name) 

-

101 api_url = ( 

-

102 "https://dashboard.snapcraft.io/dev/api/" 

-

103 "snaps/{}/binary-metadata?conflict_on_update=true" 

-

104 ).format(self.snap_id) 

-

105 

-

106 responses.add(responses.GET, api_url, json=[], status=200) 

-

107 

-

108 changes = {"images": []} 

-

109 data = dict(snap_id=self.snap_id, changes=json.dumps(changes)) 

-

110 

-

111 super().setUp( 

-

112 snap_name=snap_name, 

-

113 endpoint_url=endpoint_url, 

-

114 method_endpoint="POST", 

-

115 api_url=api_url, 

-

116 method_api="PUT", 

-

117 data=data, 

-

118 ) 

-

119 

-

120 @responses.activate 

-

121 def test_upload_new_screenshot(self): 

-

122 responses.add( 

-

123 responses.PUT, self.api_url, json={"totot": "toto"}, status=200 

-

124 ) 

-

125 

-

126 changes = { 

-

127 "images": [ 

-

128 { 

-

129 "file": {}, 

-

130 "url": "blob:this_is_a_blob", 

-

131 "name": "blue.png", 

-

132 "type": "screenshot", 

-

133 "status": "new", 

-

134 } 

-

135 ] 

-

136 } 

-

137 

-

138 data = dict( 

-

139 screenshots=[(io.BytesIO(b"my file contents"), "blue.png")], 

-

140 snap_id=self.snap_id, 

-

141 changes=json.dumps(changes), 

-

142 ) 

-

143 

-

144 response = self.client.post( 

-

145 self.endpoint_url, content_type="multipart/form-data", data=data 

-

146 ) 

-

147 

-

148 self.assertEqual(2, len(responses.calls)) 

-

149 called = responses.calls[0] 

-

150 self.assertEqual(self.api_url, called.request.url) 

-

151 self.assertEqual("GET", called.request.method) 

-

152 self.assertEqual( 

-

153 self.authorization, called.request.headers.get("Authorization") 

-

154 ) 

-

155 

-

156 called = responses.calls[1] 

-

157 self.assertEqual(self.api_url, called.request.url) 

-

158 self.assertEqual("PUT", called.request.method) 

-

159 self.assertEqual( 

-

160 self.authorization, called.request.headers.get("Authorization") 

-

161 ) 

-

162 

-

163 self.assertIn(b'"key": "blue.png"', called.request.body) 

-

164 self.assertIn(b'"type": "screenshot"', called.request.body) 

-

165 self.assertIn(b'"filename": "blue.png"', called.request.body) 

-

166 hash_screenshot = ( 

-

167 '"hash": ' 

-

168 '"114d70ba7d04c76d8c217c970f99682025c89b1a6ffe91eb9045653b4b954eb9' 

-

169 ) 

-

170 self.assertIn( 

-

171 bytes(hash_screenshot, encoding="utf-8"), called.request.body 

-

172 ) 

-

173 

-

174 assert response.status_code == 302 

-

175 assert response.location == f"{self._get_location()}.json" 

-

176 

-

177 @responses.activate 

-

178 def test_upload_new_icon(self): 

-

179 responses.add(responses.PUT, self.api_url, json={}, status=200) 

-

180 

-

181 changes = { 

-

182 "images": [ 

-

183 { 

-

184 "file": {}, 

-

185 "url": "blob:this_is_a_blob", 

-

186 "name": "blue.png", 

-

187 "type": "icon", 

-

188 "status": "new", 

-

189 } 

-

190 ] 

-

191 } 

-

192 

-

193 data = dict( 

-

194 icon=[(io.BytesIO(b"my file contents"), "blue.png")], 

-

195 snap_id=self.snap_id, 

-

196 changes=json.dumps(changes), 

-

197 ) 

-

198 

-

199 response = self.client.post( 

-

200 self.endpoint_url, content_type="multipart/form-data", data=data 

-

201 ) 

-

202 

-

203 self.assertEqual(2, len(responses.calls)) 

-

204 called = responses.calls[0] 

-

205 self.assertEqual(self.api_url, called.request.url) 

-

206 self.assertEqual("GET", called.request.method) 

-

207 self.assertEqual( 

-

208 self.authorization, called.request.headers.get("Authorization") 

-

209 ) 

-

210 

-

211 called = responses.calls[1] 

-

212 self.assertEqual(self.api_url, called.request.url) 

-

213 self.assertEqual("PUT", called.request.method) 

-

214 self.assertEqual( 

-

215 self.authorization, called.request.headers.get("Authorization") 

-

216 ) 

-

217 

-

218 self.assertIn(b'"key": "blue.png"', called.request.body) 

-

219 self.assertIn(b'"type": "icon"', called.request.body) 

-

220 self.assertIn(b'"filename": "blue.png"', called.request.body) 

-

221 hash_screenshot = ( 

-

222 '"hash": ' 

-

223 '"114d70ba7d04c76d8c217c970f99682025c89b1a6ffe91eb9045653b4b954eb9' 

-

224 ) 

-

225 self.assertIn( 

-

226 bytes(hash_screenshot, encoding="utf-8"), called.request.body 

-

227 ) 

-

228 

-

229 assert response.status_code == 302 

-

230 assert response.location == f"{self._get_location()}.json" 

-

231 

-

232 @responses.activate 

-

233 def test_upload_new_screenshot_with_existing_ones(self): 

-

234 responses.reset() 

-

235 

-

236 current_screenshots = [ 

-

237 { 

-

238 "url": "URL", 

-

239 "hash": "HASH", 

-

240 "type": "screenshot", 

-

241 "filename": "red.png", 

-

242 } 

-

243 ] 

-

244 responses.add( 

-

245 responses.GET, self.api_url, json=current_screenshots, status=200 

-

246 ) 

-

247 responses.add(responses.PUT, self.api_url, json={}, status=200) 

-

248 

-

249 changes = { 

-

250 "images": [ 

-

251 { 

-

252 "file": {}, 

-

253 "url": "blob:this_is_a_blob", 

-

254 "name": "blue.png", 

-

255 "type": "icon", 

-

256 "status": "new", 

-

257 }, 

-

258 {"url": "URL", "type": "screenshot", "status": "uploaded"}, 

-

259 ] 

-

260 } 

-

261 

-

262 data = dict( 

-

263 screenshots=[(io.BytesIO(b"my file contents"), "blue.png")], 

-

264 snap_id=self.snap_id, 

-

265 changes=json.dumps(changes), 

-

266 ) 

-

267 

-

268 response = self.client.post( 

-

269 self.endpoint_url, content_type="multipart/form-data", data=data 

-

270 ) 

-

271 

-

272 self.assertEqual(2, len(responses.calls)) 

-

273 called = responses.calls[0] 

-

274 self.assertEqual(self.api_url, called.request.url) 

-

275 self.assertEqual("GET", called.request.method) 

-

276 self.assertEqual( 

-

277 self.authorization, called.request.headers.get("Authorization") 

-

278 ) 

-

279 

-

280 called = responses.calls[1] 

-

281 self.assertEqual(self.api_url, called.request.url) 

-

282 self.assertEqual("PUT", called.request.method) 

-

283 self.assertEqual( 

-

284 self.authorization, called.request.headers.get("Authorization") 

-

285 ) 

-

286 

-

287 self.assertIn(b'"key": "blue.png"', called.request.body) 

-

288 self.assertIn(b'"type": "screenshot"', called.request.body) 

-

289 self.assertIn(b'"filename": "blue.png"', called.request.body) 

-

290 hash_screenshot = ( 

-

291 '"hash": ' 

-

292 '"114d70ba7d04c76d8c217c970f99682025c89b1a6ffe91eb9045653b4b954eb9' 

-

293 ) 

-

294 self.assertIn( 

-

295 bytes(hash_screenshot, encoding="utf-8"), called.request.body 

-

296 ) 

-

297 

-

298 self.assertIn(b'"url": "URL"', called.request.body) 

-

299 self.assertIn(b'"hash": "HASH"', called.request.body) 

-

300 self.assertIn(b'"type": "screenshot"', called.request.body) 

-

301 self.assertIn(b'"filename": "red.png"', called.request.body) 

-

302 

-

303 assert response.status_code == 302 

-

304 assert response.location == f"{self._get_location()}.json" 

-

305 

-

306 @responses.activate 

-

307 def test_upload_duplicated_screenshot(self): 

-

308 responses.reset() 

-

309 

-

310 current_screenshots = [] 

-

311 responses.add( 

-

312 responses.GET, self.api_url, json=current_screenshots, status=200 

-

313 ) 

-

314 responses.add(responses.PUT, self.api_url, json={}, status=200) 

-

315 

-

316 changes = { 

-

317 "images": [ 

-

318 { 

-

319 "file": {}, 

-

320 "url": "blob:this_is_a_blob", 

-

321 "name": "blue.png", 

-

322 "type": "icon", 

-

323 "status": "new", 

-

324 }, 

-

325 { 

-

326 "file": {}, 

-

327 "url": "blob:this_is_a_blob", 

-

328 "name": "blue.png", 

-

329 "type": "icon", 

-

330 "status": "new", 

-

331 }, 

-

332 ] 

-

333 } 

-

334 

-

335 data = dict( 

-

336 screenshots=[(io.BytesIO(b"my file contents"), "blue.png")], 

-

337 snap_id=self.snap_id, 

-

338 changes=json.dumps(changes), 

-

339 ) 

-

340 

-

341 response = self.client.post( 

-

342 self.endpoint_url, content_type="multipart/form-data", data=data 

-

343 ) 

-

344 

-

345 self.assertEqual(2, len(responses.calls)) 

-

346 called = responses.calls[0] 

-

347 self.assertEqual(self.api_url, called.request.url) 

-

348 self.assertEqual("GET", called.request.method) 

-

349 self.assertEqual( 

-

350 self.authorization, called.request.headers.get("Authorization") 

-

351 ) 

-

352 

-

353 called = responses.calls[1] 

-

354 self.assertEqual(self.api_url, called.request.url) 

-

355 self.assertEqual("PUT", called.request.method) 

-

356 self.assertEqual( 

-

357 self.authorization, called.request.headers.get("Authorization") 

-

358 ) 

-

359 

-

360 self.assertIn(b'"key": "blue.png"', called.request.body) 

-

361 self.assertIn(b'"type": "screenshot"', called.request.body) 

-

362 self.assertIn(b'"filename": "blue.png"', called.request.body) 

-

363 hash_screenshot = ( 

-

364 '"hash": ' 

-

365 '"114d70ba7d04c76d8c217c970f99682025c89b1a6ffe91eb9045653b4b954eb9' 

-

366 ) 

-

367 self.assertIn( 

-

368 bytes(hash_screenshot, encoding="utf-8"), called.request.body 

-

369 ) 

-

370 

-

371 assert called.request.body.count(b'"key": "blue.png"') == 1 

-

372 assert response.status_code == 302 

-

373 assert response.location == f"{self._get_location()}.json" 

-

374 

-

375 @responses.activate 

-

376 def test_upload_screenshot_with_duplicates_current_ones(self): 

-

377 responses.reset() 

-

378 

-

379 current_screenshots = [ 

-

380 { 

-

381 "url": "URL", 

-

382 "hash": "HASH", 

-

383 "type": "screenshot", 

-

384 "filename": "red.png", 

-

385 }, 

-

386 { 

-

387 "url": "URL", 

-

388 "hash": "HASH", 

-

389 "type": "screenshot", 

-

390 "filename": "red.png", 

-

391 }, 

-

392 ] 

-

393 responses.add( 

-

394 responses.GET, self.api_url, json=current_screenshots, status=200 

-

395 ) 

-

396 responses.add(responses.PUT, self.api_url, json={}, status=200) 

-

397 

-

398 changes = { 

-

399 "images": [ 

-

400 { 

-

401 "file": {}, 

-

402 "url": "blob:this_is_a_blob", 

-

403 "name": "blue.png", 

-

404 "type": "icon", 

-

405 "status": "new", 

-

406 }, 

-

407 {"url": "URL", "type": "screenshot", "status": "uploaded"}, 

-

408 ] 

-

409 } 

-

410 

-

411 data = dict( 

-

412 screenshots=[(io.BytesIO(b"my file contents"), "blue.png")], 

-

413 snap_id=self.snap_id, 

-

414 changes=json.dumps(changes), 

-

415 ) 

-

416 

-

417 response = self.client.post( 

-

418 self.endpoint_url, content_type="multipart/form-data", data=data 

-

419 ) 

-

420 

-

421 self.assertEqual(2, len(responses.calls)) 

-

422 called = responses.calls[0] 

-

423 self.assertEqual(self.api_url, called.request.url) 

-

424 self.assertEqual("GET", called.request.method) 

-

425 self.assertEqual( 

-

426 self.authorization, called.request.headers.get("Authorization") 

-

427 ) 

-

428 

-

429 called = responses.calls[1] 

-

430 self.assertEqual(self.api_url, called.request.url) 

-

431 self.assertEqual("PUT", called.request.method) 

-

432 self.assertEqual( 

-

433 self.authorization, called.request.headers.get("Authorization") 

-

434 ) 

-

435 

-

436 self.assertIn(b'"key": "blue.png"', called.request.body) 

-

437 self.assertIn(b'"type": "screenshot"', called.request.body) 

-

438 self.assertIn(b'"filename": "blue.png"', called.request.body) 

-

439 hash_screenshot = ( 

-

440 '"hash": ' 

-

441 '"114d70ba7d04c76d8c217c970f99682025c89b1a6ffe91eb9045653b4b954eb9' 

-

442 ) 

-

443 self.assertIn( 

-

444 bytes(hash_screenshot, encoding="utf-8"), called.request.body 

-

445 ) 

-

446 

-

447 self.assertIn(b'"url": "URL"', called.request.body) 

-

448 self.assertIn(b'"hash": "HASH"', called.request.body) 

-

449 self.assertIn(b'"type": "screenshot"', called.request.body) 

-

450 self.assertIn(b'"filename": "red.png"', called.request.body) 

-

451 

-

452 assert called.request.body.count(b'"url": "URL"') == 1 

-

453 assert response.status_code == 302 

-

454 assert response.location == f"{self._get_location()}.json" 

-
- - - diff --git a/coverage/python/tests_publisher_snaps_tests_post_close_channel_py.html b/coverage/python/tests_publisher_snaps_tests_post_close_channel_py.html index 67f7539de..0ec8e782c 100644 --- a/coverage/python/tests_publisher_snaps_tests_post_close_channel_py.html +++ b/coverage/python/tests_publisher_snaps_tests_post_close_channel_py.html @@ -198,7 +198,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_post_default_track_py.html b/coverage/python/tests_publisher_snaps_tests_post_default_track_py.html index 62d01af93..7fece1f0b 100644 --- a/coverage/python/tests_publisher_snaps_tests_post_default_track_py.html +++ b/coverage/python/tests_publisher_snaps_tests_post_default_track_py.html @@ -199,7 +199,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_post_listing_py.html b/coverage/python/tests_publisher_snaps_tests_post_listing_py.html index 593b2f8fb..b53608263 100644 --- a/coverage/python/tests_publisher_snaps_tests_post_listing_py.html +++ b/coverage/python/tests_publisher_snaps_tests_post_listing_py.html @@ -22,8 +22,8 @@

Coverage for tests/publisher/snaps/tests_post_listing.py :

Show keyboard shortcuts

- 163 statements   - + 48 statements   +

@@ -61,7 +61,7 @@

7class PostListingPageNotAuth(BaseTestCases.EndpointLoggedOut): 

8 def setUp(self): 

9 snap_name = "test-snap" 

-

10 endpoint_url = "/{}/listing".format(snap_name) 

+

10 endpoint_url = "/api/{}/listing".format(snap_name) 

11 

12 super().setUp( 

13 snap_name=snap_name, 

@@ -75,7 +75,7 @@

21 self.snap_id = "complexId" 

22 

23 snap_name = "test-snap" 

-

24 endpoint_url = "/{}/listing".format(snap_name) 

+

24 endpoint_url = "/api/{}/listing".format(snap_name) 

25 api_url = ( 

26 "https://dashboard.snapcraft.io/dev/api/" 

27 "snaps/{}/metadata?conflict_on_update=true" 

@@ -97,386 +97,71 @@

43 def test_post_no_data(self): 

44 response = self.client.post(self.endpoint_url) 

45 

-

46 assert response.status_code == 302 

-

47 assert response.location == f"{self._get_location()}.json" 

-

48 

-

49 @responses.activate 

-

50 def test_update_invalid_field(self): 

-

51 response = self.client.post( 

-

52 self.endpoint_url, 

-

53 data={"changes": '{"dumb_field": "this is a dumb field"}'}, 

-

54 ) 

-

55 

-

56 assert 0 == len(responses.calls) 

-

57 assert response.status_code == 302 

-

58 assert response.location == f"{self._get_location()}.json" 

-

59 

-

60 @responses.activate 

-

61 def test_update_valid_field(self): 

-

62 responses.add(responses.PUT, self.api_url, json={}, status=200) 

+

46 assert response.status_code == 200 

+

47 

+

48 @responses.activate 

+

49 def test_update_invalid_field(self): 

+

50 response = self.client.post( 

+

51 self.endpoint_url, 

+

52 data={"changes": '{"dumb_field": "this is a dumb field"}'}, 

+

53 ) 

+

54 

+

55 assert 0 == len(responses.calls) 

+

56 assert response.status_code == 200 

+

57 

+

58 @responses.activate 

+

59 def test_update_valid_field(self): 

+

60 responses.add(responses.PUT, self.api_url, json={}, status=200) 

+

61 

+

62 changes = {"description": "New description"} 

63 

-

64 changes = {"description": "New description"} 

-

65 

-

66 response = self.client.post( 

-

67 self.endpoint_url, 

-

68 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

-

69 ) 

-

70 

-

71 self.assertEqual(1, len(responses.calls)) 

-

72 called = responses.calls[0] 

-

73 self.assertEqual(self.api_url, called.request.url) 

-

74 self.assertEqual( 

-

75 self.authorization, called.request.headers.get("Authorization") 

-

76 ) 

-

77 self.assertEqual( 

-

78 b'{"description": "New description"}', 

-

79 called.request.body, 

-

80 ) 

+

64 response = self.client.post( 

+

65 self.endpoint_url, 

+

66 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

+

67 ) 

+

68 

+

69 self.assertEqual(1, len(responses.calls)) 

+

70 called = responses.calls[0] 

+

71 self.assertEqual(self.api_url, called.request.url) 

+

72 self.assertEqual( 

+

73 self.authorization, called.request.headers.get("Authorization") 

+

74 ) 

+

75 self.assertEqual( 

+

76 b'{"description": "New description"}', 

+

77 called.request.body, 

+

78 ) 

+

79 

+

80 assert response.status_code == 200 

81 

-

82 assert response.status_code == 302 

-

83 assert response.location == f"{self._get_location()}.json" 

-

84 

-

85 @responses.activate 

-

86 def test_update_description_with_carriage_return(self): 

-

87 responses.add(responses.PUT, self.api_url, json={}, status=200) 

-

88 

-

89 changes = {"description": "This is a description\r\n"} 

-

90 

-

91 response = self.client.post( 

-

92 self.endpoint_url, 

-

93 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

-

94 ) 

-

95 

-

96 self.assertEqual(1, len(responses.calls)) 

-

97 called = responses.calls[0] 

-

98 self.assertEqual(self.api_url, called.request.url) 

+

82 @responses.activate 

+

83 def test_update_description_with_carriage_return(self): 

+

84 responses.add(responses.PUT, self.api_url, json={}, status=200) 

+

85 

+

86 changes = {"description": "This is a description\r\n"} 

+

87 

+

88 response = self.client.post( 

+

89 self.endpoint_url, 

+

90 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

+

91 ) 

+

92 

+

93 self.assertEqual(1, len(responses.calls)) 

+

94 called = responses.calls[0] 

+

95 self.assertEqual(self.api_url, called.request.url) 

+

96 self.assertEqual( 

+

97 self.authorization, called.request.headers.get("Authorization") 

+

98 ) 

99 self.assertEqual( 

-

100 self.authorization, called.request.headers.get("Authorization") 

-

101 ) 

-

102 self.assertEqual( 

-

103 b'{"description": "This is a description\\n"}', 

-

104 called.request.body, 

-

105 ) 

-

106 

-

107 assert response.status_code == 302 

-

108 assert response.location == f"{self._get_location()}.json" 

-

109 

-

110 @responses.activate 

-

111 def test_return_error_udpate_one_field(self): 

-

112 metadata_payload = { 

-

113 "error_list": [{"code": "code", "message": "message"}] 

-

114 } 

-

115 

-

116 responses.add( 

-

117 responses.PUT, self.api_url, json=metadata_payload, status=400 

-

118 ) 

-

119 

-

120 info_url = "https://dashboard.snapcraft.io/dev/api/snaps/info/{}" 

-

121 info_url = info_url.format(self.snap_name) 

-

122 

-

123 payload = { 

-

124 "snap_id": self.snap_id, 

-

125 "snap_name": self.snap_name, 

-

126 "title": "Snap title", 

-

127 "summary": "This is a summary", 

-

128 "description": "This is a description", 

-

129 "media": [], 

-

130 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

131 "private": True, 

-

132 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

133 "contact": "contact address", 

-

134 "website": "website_url", 

-

135 "public_metrics_enabled": True, 

-

136 "public_metrics_blacklist": True, 

-

137 "license": "test OR testing", 

-

138 "video_urls": [], 

-

139 "categories": {"items": []}, 

-

140 "links": {}, 

-

141 } 

-

142 

-

143 responses.add(responses.GET, info_url, json=payload, status=200) 

-

144 responses.add( 

-

145 responses.GET, 

-

146 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

147 json=[], 

-

148 status=200, 

-

149 ) 

-

150 

-

151 changes = {"description": "This is an updated description"} 

-

152 

-

153 response = self.client.post( 

-

154 self.endpoint_url, 

-

155 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

-

156 ) 

-

157 

-

158 self.assertEqual(3, len(responses.calls)) 

-

159 called = responses.calls[0] 

-

160 self.assertEqual(self.api_url, called.request.url) 

-

161 self.assertEqual( 

-

162 self.authorization, called.request.headers.get("Authorization") 

-

163 ) 

-

164 self.assertEqual( 

-

165 b'{"description": "This is an updated description"}', 

-

166 called.request.body, 

-

167 ) 

-

168 called = responses.calls[1] 

-

169 self.assertEqual(info_url, called.request.url) 

-

170 self.assertEqual( 

-

171 self.authorization, called.request.headers.get("Authorization") 

-

172 ) 

-

173 

-

174 self.assertEqual(response.status_code, 200) 

-

175 self.assert_template_used("publisher/listing.html") 

-

176 

-

177 self.assert_context("snap_id", self.snap_id) 

-

178 self.assert_context("snap_name", self.snap_name) 

-

179 # udpated field 

-

180 self.assert_context("description", "This is an updated description") 

-

181 

-

182 self.assert_context("snap_title", "Snap title") 

-

183 self.assert_context("summary", "This is a summary") 

-

184 self.assert_context("icon_url", None) 

-

185 self.assert_context("publisher_name", "The publisher") 

-

186 self.assert_context("username", "toto") 

-

187 self.assert_context("screenshot_urls", []) 

-

188 self.assert_context("website", "website_url") 

-

189 self.assert_context("is_on_stable", False) 

-

190 self.assert_context("public_metrics_enabled", True) 

-

191 self.assert_context("public_metrics_blacklist", True) 

-

192 self.assert_context("license", "test OR testing") 

-

193 self.assert_context("video_urls", []) 

-

194 

-

195 @responses.activate 

-

196 def test_return_error_udpate_all_field(self): 

-

197 metadata_payload = { 

-

198 "error_list": [{"code": "code", "message": "message"}] 

-

199 } 

-

200 

-

201 responses.add( 

-

202 responses.PUT, self.api_url, json=metadata_payload, status=400 

-

203 ) 

-

204 

-

205 info_url = "https://dashboard.snapcraft.io/dev/api/snaps/info/{}" 

-

206 info_url = info_url.format(self.snap_name) 

-

207 

-

208 payload = { 

-

209 "snap_id": self.snap_id, 

-

210 "snap_name": self.snap_name, 

-

211 "title": "Snap title", 

-

212 "summary": "This is a summary", 

-

213 "description": "This is a description", 

-

214 "media": [], 

-

215 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

216 "private": True, 

-

217 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

218 "contact": "contact address", 

-

219 "website": "website_url", 

-

220 "public_metrics_enabled": False, 

-

221 "public_metrics_blacklist": True, 

-

222 "license": "test OR testing", 

-

223 "video_urls": [], 

-

224 "categories": {"items": []}, 

-

225 "links": {}, 

-

226 } 

-

227 

-

228 responses.add(responses.GET, info_url, json=payload, status=200) 

-

229 responses.add( 

-

230 responses.GET, 

-

231 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

232 json=[], 

-

233 status=200, 

-

234 ) 

-

235 

-

236 changes = { 

-

237 "snap_title": "New title", 

-

238 "summary": "New summary", 

-

239 "description": "New description", 

-

240 "icon_url": None, 

-

241 "publisher_name": "New publisher", 

-

242 "screenshot_urls": [], 

-

243 "website": "New website", 

-

244 "public_metrics_enabled": True, 

-

245 "public_metrics_blacklist": "new metric1,new metric2", 

-

246 "license": ["test1", "test", "testing"], 

-

247 } 

-

248 

-

249 response = self.client.post( 

-

250 self.endpoint_url, 

-

251 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

-

252 ) 

-

253 

-

254 self.assertEqual(3, len(responses.calls)) 

-

255 called = responses.calls[0] 

-

256 self.assertEqual(self.api_url, called.request.url) 

-

257 self.assertEqual( 

-

258 self.authorization, called.request.headers.get("Authorization") 

-

259 ) 

-

260 called = responses.calls[1] 

-

261 self.assertEqual(info_url, called.request.url) 

-

262 self.assertEqual( 

-

263 self.authorization, called.request.headers.get("Authorization") 

-

264 ) 

-

265 

-

266 self.assertEqual(response.status_code, 200) 

-

267 self.assert_template_used("publisher/listing.html") 

-

268 

-

269 # Not updatable fields 

-

270 self.assert_context("snap_id", self.snap_id) 

-

271 self.assert_context("snap_name", self.snap_name) 

-

272 self.assert_context("icon_url", None) 

-

273 self.assert_context("publisher_name", "The publisher") 

-

274 self.assert_context("username", "toto") 

-

275 self.assert_context("screenshot_urls", []) 

-

276 self.assert_context("snap_title", "Snap title") 

-

277 self.assert_context("is_on_stable", False) 

-

278 self.assert_context("public_metrics_enabled", False) 

-

279 self.assert_context("public_metrics_blacklist", True) 

-

280 self.assert_context("video_urls", []) 

-

281 self.assert_context("license", "test OR testing") 

-

282 

-

283 # All updatable fields 

-

284 self.assert_context("summary", "New summary") 

-

285 self.assert_context("description", "New description") 

-

286 self.assert_context("website", "New website") 

-

287 

-

288 @responses.activate 

-

289 def test_return_error_invalid_field(self): 

-

290 metadata_payload = { 

-

291 "error_list": [ 

-

292 { 

-

293 "code": "invalid-field", 

-

294 "message": "error message", 

-

295 "extra": {"name": "description"}, 

-

296 } 

-

297 ] 

-

298 } 

-

299 

-

300 responses.add( 

-

301 responses.PUT, self.api_url, json=metadata_payload, status=400 

-

302 ) 

-

303 

-

304 info_url = "https://dashboard.snapcraft.io/dev/api/snaps/info/{}" 

-

305 info_url = info_url.format(self.snap_name) 

-

306 

-

307 payload = { 

-

308 "snap_id": self.snap_id, 

-

309 "snap_name": self.snap_name, 

-

310 "title": "Snap title", 

-

311 "summary": "This is a summary", 

-

312 "description": "This is a description", 

-

313 "media": [], 

-

314 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

315 "private": True, 

-

316 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

317 "contact": "contact adress", 

-

318 "website": "website_url", 

-

319 "public_metrics_enabled": True, 

-

320 "public_metrics_blacklist": True, 

-

321 "license": "test OR testing", 

-

322 "video_urls": [], 

-

323 "categories": {"items": []}, 

-

324 "links": {}, 

-

325 } 

-

326 

-

327 responses.add(responses.GET, info_url, json=payload, status=200) 

-

328 responses.add( 

-

329 responses.GET, 

-

330 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

331 json=[], 

-

332 status=200, 

-

333 ) 

-

334 

-

335 changes = {"description": "This is an updated description"} 

-

336 

-

337 response = self.client.post( 

-

338 self.endpoint_url, 

-

339 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

-

340 ) 

-

341 

-

342 self.assertEqual(3, len(responses.calls)) 

-

343 called = responses.calls[0] 

-

344 self.assertEqual(self.api_url, called.request.url) 

-

345 self.assertEqual( 

-

346 self.authorization, called.request.headers.get("Authorization") 

-

347 ) 

-

348 called = responses.calls[1] 

-

349 self.assertEqual(info_url, called.request.url) 

-

350 self.assertEqual( 

-

351 self.authorization, called.request.headers.get("Authorization") 

-

352 ) 

-

353 

-

354 self.assertEqual(response.status_code, 200) 

-

355 self.assert_template_used("publisher/listing.html") 

-

356 

-

357 self.assert_context("field_errors", {"description": "error message"}) 

-

358 

-

359 @responses.activate 

-

360 def test_return_error_udpate_with_failed_categories_api(self): 

-

361 metadata_payload = { 

-

362 "error_list": [{"code": "code", "message": "message"}] 

-

363 } 

-

364 

-

365 responses.add( 

-

366 responses.PUT, self.api_url, json=metadata_payload, status=400 

-

367 ) 

-

368 

-

369 info_url = "https://dashboard.snapcraft.io/dev/api/snaps/info/{}" 

-

370 info_url = info_url.format(self.snap_name) 

-

371 

-

372 payload = { 

-

373 "snap_id": self.snap_id, 

-

374 "snap_name": self.snap_name, 

-

375 "title": "Snap title", 

-

376 "summary": "This is a summary", 

-

377 "description": "This is a description", 

-

378 "media": [], 

-

379 "publisher": {"display-name": "The publisher", "username": "toto"}, 

-

380 "private": True, 

-

381 "channel_maps_list": [{"map": [{"info": "info"}]}], 

-

382 "contact": "contact address", 

-

383 "website": "website_url", 

-

384 "public_metrics_enabled": False, 

-

385 "public_metrics_blacklist": True, 

-

386 "license": "test OR testing", 

-

387 "video_urls": [], 

-

388 "categories": {"items": []}, 

-

389 "links": {}, 

-

390 } 

-

391 

-

392 responses.add(responses.GET, info_url, json=payload, status=200) 

-

393 responses.add( 

-

394 responses.GET, 

-

395 "https://api.snapcraft.io/v2/snaps/categories?type=shared", 

-

396 json=[], 

-

397 status=400, 

-

398 ) 

-

399 

-

400 changes = {"description": "This is an updated description"} 

-

401 

-

402 self.client.post( 

-

403 self.endpoint_url, 

-

404 data={"changes": json.dumps(changes), "snap_id": self.snap_id}, 

-

405 ) 

-

406 

-

407 self.assertEqual(3, len(responses.calls)) 

-

408 called = responses.calls[0] 

-

409 self.assertEqual(self.api_url, called.request.url) 

-

410 self.assertEqual( 

-

411 self.authorization, called.request.headers.get("Authorization") 

-

412 ) 

-

413 called = responses.calls[1] 

-

414 self.assertEqual(info_url, called.request.url) 

-

415 self.assertEqual( 

-

416 self.authorization, called.request.headers.get("Authorization") 

-

417 ) 

-

418 

-

419 self.assert_context("categories", []) 

+

100 b'{"description": "This is a description\\n"}', 

+

101 called.request.body, 

+

102 ) 

+

103 

+

104 assert response.status_code == 200 

diff --git a/coverage/python/tests_publisher_snaps_tests_post_release_py.html b/coverage/python/tests_publisher_snaps_tests_post_release_py.html index 7e43f673d..2c0c20b81 100644 --- a/coverage/python/tests_publisher_snaps_tests_post_release_py.html +++ b/coverage/python/tests_publisher_snaps_tests_post_release_py.html @@ -173,7 +173,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_post_settings_py.html b/coverage/python/tests_publisher_snaps_tests_post_settings_py.html index 8555e09b3..1f95e61c5 100644 --- a/coverage/python/tests_publisher_snaps_tests_post_settings_py.html +++ b/coverage/python/tests_publisher_snaps_tests_post_settings_py.html @@ -383,7 +383,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_publicise_badges_py.html b/coverage/python/tests_publisher_snaps_tests_publicise_badges_py.html index 24251aa0b..ad870e2ca 100644 --- a/coverage/python/tests_publisher_snaps_tests_publicise_badges_py.html +++ b/coverage/python/tests_publisher_snaps_tests_publicise_badges_py.html @@ -184,7 +184,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_publicise_cards_py.html b/coverage/python/tests_publisher_snaps_tests_publicise_cards_py.html index a22f19153..2226d9dd9 100644 --- a/coverage/python/tests_publisher_snaps_tests_publicise_cards_py.html +++ b/coverage/python/tests_publisher_snaps_tests_publicise_cards_py.html @@ -171,7 +171,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_publicise_py.html b/coverage/python/tests_publisher_snaps_tests_publicise_py.html index 69ba13f77..2b938b618 100644 --- a/coverage/python/tests_publisher_snaps_tests_publicise_py.html +++ b/coverage/python/tests_publisher_snaps_tests_publicise_py.html @@ -148,7 +148,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_revision_py.html b/coverage/python/tests_publisher_snaps_tests_revision_py.html index eca8ba82c..e2de08bd6 100644 --- a/coverage/python/tests_publisher_snaps_tests_revision_py.html +++ b/coverage/python/tests_publisher_snaps_tests_revision_py.html @@ -144,7 +144,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_snaps_tests_settings_py.html b/coverage/python/tests_publisher_snaps_tests_settings_py.html index 440d3aa66..a8c26ff43 100644 --- a/coverage/python/tests_publisher_snaps_tests_settings_py.html +++ b/coverage/python/tests_publisher_snaps_tests_settings_py.html @@ -157,7 +157,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_account_logout_py.html b/coverage/python/tests_publisher_tests_account_logout_py.html index 6e85ba6ce..fc09a4052 100644 --- a/coverage/python/tests_publisher_tests_account_logout_py.html +++ b/coverage/python/tests_publisher_tests_account_logout_py.html @@ -77,7 +77,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_account_snaps_metrics_py.html b/coverage/python/tests_publisher_tests_account_snaps_metrics_py.html index 8b8f34908..8e2176a28 100644 --- a/coverage/python/tests_publisher_tests_account_snaps_metrics_py.html +++ b/coverage/python/tests_publisher_tests_account_snaps_metrics_py.html @@ -172,7 +172,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_account_snaps_py.html b/coverage/python/tests_publisher_tests_account_snaps_py.html index b9192dbe9..df5fe2142 100644 --- a/coverage/python/tests_publisher_tests_account_snaps_py.html +++ b/coverage/python/tests_publisher_tests_account_snaps_py.html @@ -417,7 +417,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_agreement_py.html b/coverage/python/tests_publisher_tests_agreement_py.html index 4217efaa4..fd6e94358 100644 --- a/coverage/python/tests_publisher_tests_agreement_py.html +++ b/coverage/python/tests_publisher_tests_agreement_py.html @@ -116,7 +116,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_api_snaps_py.html b/coverage/python/tests_publisher_tests_api_snaps_py.html index f1dff7879..a6618add3 100644 --- a/coverage/python/tests_publisher_tests_api_snaps_py.html +++ b/coverage/python/tests_publisher_tests_api_snaps_py.html @@ -238,7 +238,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_get_package_metadata_py.html b/coverage/python/tests_publisher_tests_get_package_metadata_py.html index ba9c6ba3a..8a3b93167 100644 --- a/coverage/python/tests_publisher_tests_get_package_metadata_py.html +++ b/coverage/python/tests_publisher_tests_get_package_metadata_py.html @@ -109,7 +109,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_post_account_details_py.html b/coverage/python/tests_publisher_tests_post_account_details_py.html index da27b0511..9d4c049fa 100644 --- a/coverage/python/tests_publisher_tests_post_account_details_py.html +++ b/coverage/python/tests_publisher_tests_post_account_details_py.html @@ -112,7 +112,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_publisher_logic_py.html b/coverage/python/tests_publisher_tests_publisher_logic_py.html index a41382f46..399274ede 100644 --- a/coverage/python/tests_publisher_tests_publisher_logic_py.html +++ b/coverage/python/tests_publisher_tests_publisher_logic_py.html @@ -182,7 +182,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_publisher_py.html b/coverage/python/tests_publisher_tests_publisher_py.html index c9e4c8bad..18cb92649 100644 --- a/coverage/python/tests_publisher_tests_publisher_py.html +++ b/coverage/python/tests_publisher_tests_publisher_py.html @@ -246,7 +246,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_register_name_dispute_py.html b/coverage/python/tests_publisher_tests_register_name_dispute_py.html index 945a0e899..cd07c2222 100644 --- a/coverage/python/tests_publisher_tests_register_name_dispute_py.html +++ b/coverage/python/tests_publisher_tests_register_name_dispute_py.html @@ -212,7 +212,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_register_name_json_py.html b/coverage/python/tests_publisher_tests_register_name_json_py.html index 005130763..07e5386ea 100644 --- a/coverage/python/tests_publisher_tests_register_name_json_py.html +++ b/coverage/python/tests_publisher_tests_register_name_json_py.html @@ -131,7 +131,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_register_name_py.html b/coverage/python/tests_publisher_tests_register_name_py.html index 157516307..e07817cdd 100644 --- a/coverage/python/tests_publisher_tests_register_name_py.html +++ b/coverage/python/tests_publisher_tests_register_name_py.html @@ -347,7 +347,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_reserved_name_dispute_py.html b/coverage/python/tests_publisher_tests_reserved_name_dispute_py.html index e141b3eb0..e7cab0595 100644 --- a/coverage/python/tests_publisher_tests_reserved_name_dispute_py.html +++ b/coverage/python/tests_publisher_tests_reserved_name_dispute_py.html @@ -110,7 +110,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_publisher_tests_username_py.html b/coverage/python/tests_publisher_tests_username_py.html index f32f10154..823fdf749 100644 --- a/coverage/python/tests_publisher_tests_username_py.html +++ b/coverage/python/tests_publisher_tests_username_py.html @@ -135,7 +135,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_snapcraft___init___py.html b/coverage/python/tests_snapcraft___init___py.html index 31cc1ca01..189a6c732 100644 --- a/coverage/python/tests_snapcraft___init___py.html +++ b/coverage/python/tests_snapcraft___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_snapcraft_tests_public_py.html b/coverage/python/tests_snapcraft_tests_public_py.html index 1376164e7..710f53af8 100644 --- a/coverage/python/tests_snapcraft_tests_public_py.html +++ b/coverage/python/tests_snapcraft_tests_public_py.html @@ -78,7 +78,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store___init___py.html b/coverage/python/tests_store___init___py.html index 8f1896b30..150370852 100644 --- a/coverage/python/tests_store___init___py.html +++ b/coverage/python/tests_store___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store_tests_details_py.html b/coverage/python/tests_store_tests_details_py.html index 1ba8b841d..0e71c80a7 100644 --- a/coverage/python/tests_store_tests_details_py.html +++ b/coverage/python/tests_store_tests_details_py.html @@ -370,7 +370,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store_tests_distro_page_py.html b/coverage/python/tests_store_tests_distro_page_py.html index b0ea86edb..95d011513 100644 --- a/coverage/python/tests_store_tests_distro_page_py.html +++ b/coverage/python/tests_store_tests_distro_page_py.html @@ -227,7 +227,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store_tests_embedded_card_py.html b/coverage/python/tests_store_tests_embedded_card_py.html index 2c4d31ac7..99a97e099 100644 --- a/coverage/python/tests_store_tests_embedded_card_py.html +++ b/coverage/python/tests_store_tests_embedded_card_py.html @@ -252,7 +252,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store_tests_github_badge_py.html b/coverage/python/tests_store_tests_github_badge_py.html index 54dbea421..5442d75c6 100644 --- a/coverage/python/tests_store_tests_github_badge_py.html +++ b/coverage/python/tests_store_tests_github_badge_py.html @@ -298,7 +298,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store_tests_public_logic_py.html b/coverage/python/tests_store_tests_public_logic_py.html index 5ae87f60c..eab7bae05 100644 --- a/coverage/python/tests_store_tests_public_logic_py.html +++ b/coverage/python/tests_store_tests_public_logic_py.html @@ -531,7 +531,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store_tests_publisher_py.html b/coverage/python/tests_store_tests_publisher_py.html index 5a11ecd16..16c169f95 100644 --- a/coverage/python/tests_store_tests_publisher_py.html +++ b/coverage/python/tests_store_tests_publisher_py.html @@ -144,7 +144,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_store_tests_validation_sets_py.html b/coverage/python/tests_store_tests_validation_sets_py.html index c37720156..c298b7187 100644 --- a/coverage/python/tests_store_tests_validation_sets_py.html +++ b/coverage/python/tests_store_tests_validation_sets_py.html @@ -76,7 +76,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_tests_badge_counter_py.html b/coverage/python/tests_tests_badge_counter_py.html index 3336e6606..96c6f2a6e 100644 --- a/coverage/python/tests_tests_badge_counter_py.html +++ b/coverage/python/tests_tests_badge_counter_py.html @@ -96,7 +96,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_tests_helpers_py.html b/coverage/python/tests_tests_helpers_py.html index 1422d1f57..cd72feb75 100644 --- a/coverage/python/tests_tests_helpers_py.html +++ b/coverage/python/tests_tests_helpers_py.html @@ -73,7 +73,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_tests_markdown_parser_py.html b/coverage/python/tests_tests_markdown_parser_py.html index f8795dbb4..d85c68ddd 100644 --- a/coverage/python/tests_tests_markdown_parser_py.html +++ b/coverage/python/tests_tests_markdown_parser_py.html @@ -234,7 +234,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_tests_requests_py.html b/coverage/python/tests_tests_requests_py.html index 5447662f2..3d1e43455 100644 --- a/coverage/python/tests_tests_requests_py.html +++ b/coverage/python/tests_tests_requests_py.html @@ -82,7 +82,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/tests_tests_templates_utils_py.html b/coverage/python/tests_tests_templates_utils_py.html index 6512a43ac..124b8a210 100644 --- a/coverage/python/tests_tests_templates_utils_py.html +++ b/coverage/python/tests_tests_templates_utils_py.html @@ -338,7 +338,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp___init___py.html b/coverage/python/webapp___init___py.html index 69d41add1..7bdb5e234 100644 --- a/coverage/python/webapp___init___py.html +++ b/coverage/python/webapp___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_admin_views_py.html b/coverage/python/webapp_admin_views_py.html index 93988809e..44e015148 100644 --- a/coverage/python/webapp_admin_views_py.html +++ b/coverage/python/webapp_admin_views_py.html @@ -767,7 +767,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_api___init___py.html b/coverage/python/webapp_api___init___py.html index e299308ab..425d2d6a5 100644 --- a/coverage/python/webapp_api___init___py.html +++ b/coverage/python/webapp_api___init___py.html @@ -58,7 +58,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_api_exceptions_py.html b/coverage/python/webapp_api_exceptions_py.html index d3cfdb1ff..005a5d31a 100644 --- a/coverage/python/webapp_api_exceptions_py.html +++ b/coverage/python/webapp_api_exceptions_py.html @@ -108,7 +108,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_api_github_py.html b/coverage/python/webapp_api_github_py.html index 73e674ac2..0afc29b50 100644 --- a/coverage/python/webapp_api_github_py.html +++ b/coverage/python/webapp_api_github_py.html @@ -507,7 +507,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_api_marketo_py.html b/coverage/python/webapp_api_marketo_py.html index ccdbec84e..618fd1904 100644 --- a/coverage/python/webapp_api_marketo_py.html +++ b/coverage/python/webapp_api_marketo_py.html @@ -173,7 +173,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_api_requests_py.html b/coverage/python/webapp_api_requests_py.html index 80085db7d..f786fca7b 100644 --- a/coverage/python/webapp_api_requests_py.html +++ b/coverage/python/webapp_api_requests_py.html @@ -108,7 +108,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_api_sso_py.html b/coverage/python/webapp_api_sso_py.html index 7a34e1806..af23e8d30 100644 --- a/coverage/python/webapp_api_sso_py.html +++ b/coverage/python/webapp_api_sso_py.html @@ -104,7 +104,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_app_py.html b/coverage/python/webapp_app_py.html index be1d7e4d0..7563505fe 100644 --- a/coverage/python/webapp_app_py.html +++ b/coverage/python/webapp_app_py.html @@ -135,7 +135,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_authentication_py.html b/coverage/python/webapp_authentication_py.html index d135d7c59..f1adc9ab4 100644 --- a/coverage/python/webapp_authentication_py.html +++ b/coverage/python/webapp_authentication_py.html @@ -158,7 +158,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_blog___init___py.html b/coverage/python/webapp_blog___init___py.html index 2228395c4..3f566bec7 100644 --- a/coverage/python/webapp_blog___init___py.html +++ b/coverage/python/webapp_blog___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_blog_views_py.html b/coverage/python/webapp_blog_views_py.html index ba7dd2106..8b6cf8eee 100644 --- a/coverage/python/webapp_blog_views_py.html +++ b/coverage/python/webapp_blog_views_py.html @@ -218,7 +218,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_config_py.html b/coverage/python/webapp_config_py.html index 32edd0f92..4b748db84 100644 --- a/coverage/python/webapp_config_py.html +++ b/coverage/python/webapp_config_py.html @@ -92,7 +92,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_decorators_py.html b/coverage/python/webapp_decorators_py.html index 58680a80f..5bfef4dce 100644 --- a/coverage/python/webapp_decorators_py.html +++ b/coverage/python/webapp_decorators_py.html @@ -98,7 +98,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_docs___init___py.html b/coverage/python/webapp_docs___init___py.html index a23e071d2..bf98abc87 100644 --- a/coverage/python/webapp_docs___init___py.html +++ b/coverage/python/webapp_docs___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_docs_views_py.html b/coverage/python/webapp_docs_views_py.html index 9bdc7028b..374135058 100644 --- a/coverage/python/webapp_docs_views_py.html +++ b/coverage/python/webapp_docs_views_py.html @@ -103,7 +103,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_extensions_py.html b/coverage/python/webapp_extensions_py.html index 51adbe1b0..c66c807ca 100644 --- a/coverage/python/webapp_extensions_py.html +++ b/coverage/python/webapp_extensions_py.html @@ -61,7 +61,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_first_snap_views_py.html b/coverage/python/webapp_first_snap_views_py.html index 2f8e91424..bbc3937ff 100644 --- a/coverage/python/webapp_first_snap_views_py.html +++ b/coverage/python/webapp_first_snap_views_py.html @@ -289,7 +289,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_handlers_py.html b/coverage/python/webapp_handlers_py.html index 8e0a8e8eb..403d771d5 100644 --- a/coverage/python/webapp_handlers_py.html +++ b/coverage/python/webapp_handlers_py.html @@ -483,7 +483,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_helpers_py.html b/coverage/python/webapp_helpers_py.html index 0d67522e3..dcb2e6fb5 100644 --- a/coverage/python/webapp_helpers_py.html +++ b/coverage/python/webapp_helpers_py.html @@ -211,7 +211,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_login_macaroon_py.html b/coverage/python/webapp_login_macaroon_py.html index ac5c77237..71bd94983 100644 --- a/coverage/python/webapp_login_macaroon_py.html +++ b/coverage/python/webapp_login_macaroon_py.html @@ -101,7 +101,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_login_oauth_views_py.html b/coverage/python/webapp_login_oauth_views_py.html index 7c187334c..a4b9473c0 100644 --- a/coverage/python/webapp_login_oauth_views_py.html +++ b/coverage/python/webapp_login_oauth_views_py.html @@ -135,7 +135,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_login_views_py.html b/coverage/python/webapp_login_views_py.html index 617e2dbeb..90e115135 100644 --- a/coverage/python/webapp_login_views_py.html +++ b/coverage/python/webapp_login_views_py.html @@ -183,7 +183,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_markdown_py.html b/coverage/python/webapp_markdown_py.html index c25d51a4c..6ccb01deb 100644 --- a/coverage/python/webapp_markdown_py.html +++ b/coverage/python/webapp_markdown_py.html @@ -119,7 +119,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_metrics_helper_py.html b/coverage/python/webapp_metrics_helper_py.html index e226e6c29..bd662aa55 100644 --- a/coverage/python/webapp_metrics_helper_py.html +++ b/coverage/python/webapp_metrics_helper_py.html @@ -188,7 +188,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_metrics_metrics_py.html b/coverage/python/webapp_metrics_metrics_py.html index 05f074848..bed1ee056 100644 --- a/coverage/python/webapp_metrics_metrics_py.html +++ b/coverage/python/webapp_metrics_metrics_py.html @@ -373,7 +373,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_packages_logic_py.html b/coverage/python/webapp_packages_logic_py.html index 2ffce7aa7..59499b8fe 100644 --- a/coverage/python/webapp_packages_logic_py.html +++ b/coverage/python/webapp_packages_logic_py.html @@ -439,7 +439,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_packages_store_packages_py.html b/coverage/python/webapp_packages_store_packages_py.html index 2ef7b9f09..70fb132c6 100644 --- a/coverage/python/webapp_packages_store_packages_py.html +++ b/coverage/python/webapp_packages_store_packages_py.html @@ -169,7 +169,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher___init___py.html b/coverage/python/webapp_publisher___init___py.html index e0a280c14..6a1cbe478 100644 --- a/coverage/python/webapp_publisher___init___py.html +++ b/coverage/python/webapp_publisher___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_github_views_py.html b/coverage/python/webapp_publisher_github_views_py.html index b4c4968fc..b5503f415 100644 --- a/coverage/python/webapp_publisher_github_views_py.html +++ b/coverage/python/webapp_publisher_github_views_py.html @@ -85,7 +85,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_build_views_py.html b/coverage/python/webapp_publisher_snaps_build_views_py.html index 58c1154c5..068daae46 100644 --- a/coverage/python/webapp_publisher_snaps_build_views_py.html +++ b/coverage/python/webapp_publisher_snaps_build_views_py.html @@ -677,7 +677,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_builds_py.html b/coverage/python/webapp_publisher_snaps_builds_py.html index a111d48de..afdd72cf0 100644 --- a/coverage/python/webapp_publisher_snaps_builds_py.html +++ b/coverage/python/webapp_publisher_snaps_builds_py.html @@ -206,7 +206,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_collaboration_views_py.html b/coverage/python/webapp_publisher_snaps_collaboration_views_py.html index 87dc05b01..ce54cb95a 100644 --- a/coverage/python/webapp_publisher_snaps_collaboration_views_py.html +++ b/coverage/python/webapp_publisher_snaps_collaboration_views_py.html @@ -91,7 +91,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_listing_views_py.html b/coverage/python/webapp_publisher_snaps_listing_views_py.html index 82e28f1eb..3eef35ba2 100644 --- a/coverage/python/webapp_publisher_snaps_listing_views_py.html +++ b/coverage/python/webapp_publisher_snaps_listing_views_py.html @@ -3,7 +3,7 @@ - Coverage for webapp/publisher/snaps/listing_views.py: 94% + Coverage for webapp/publisher/snaps/listing_views.py: 72% @@ -18,13 +18,13 @@ diff --git a/coverage/python/webapp_publisher_snaps_logic_py.html b/coverage/python/webapp_publisher_snaps_logic_py.html index ab64df4ae..7d5120aec 100644 --- a/coverage/python/webapp_publisher_snaps_logic_py.html +++ b/coverage/python/webapp_publisher_snaps_logic_py.html @@ -3,7 +3,7 @@ - Coverage for webapp/publisher/snaps/logic.py: 89% + Coverage for webapp/publisher/snaps/logic.py: 72% @@ -18,13 +18,13 @@ diff --git a/coverage/python/webapp_publisher_snaps_metrics_views_py.html b/coverage/python/webapp_publisher_snaps_metrics_views_py.html index 683deb4d9..df045e457 100644 --- a/coverage/python/webapp_publisher_snaps_metrics_views_py.html +++ b/coverage/python/webapp_publisher_snaps_metrics_views_py.html @@ -259,7 +259,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_preview_data_py.html b/coverage/python/webapp_publisher_snaps_preview_data_py.html index a33a5736b..476ed04c1 100644 --- a/coverage/python/webapp_publisher_snaps_preview_data_py.html +++ b/coverage/python/webapp_publisher_snaps_preview_data_py.html @@ -1578,7 +1578,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_publicise_views_py.html b/coverage/python/webapp_publisher_snaps_publicise_views_py.html index 74a0fd4fc..8e41fa626 100644 --- a/coverage/python/webapp_publisher_snaps_publicise_views_py.html +++ b/coverage/python/webapp_publisher_snaps_publicise_views_py.html @@ -158,7 +158,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_release_views_py.html b/coverage/python/webapp_publisher_snaps_release_views_py.html index 373174a43..8d5aeef64 100644 --- a/coverage/python/webapp_publisher_snaps_release_views_py.html +++ b/coverage/python/webapp_publisher_snaps_release_views_py.html @@ -228,7 +228,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_settings_views_py.html b/coverage/python/webapp_publisher_snaps_settings_views_py.html index 0e01187dd..5dcece956 100644 --- a/coverage/python/webapp_publisher_snaps_settings_views_py.html +++ b/coverage/python/webapp_publisher_snaps_settings_views_py.html @@ -249,7 +249,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_publisher_snaps_views_py.html b/coverage/python/webapp_publisher_snaps_views_py.html index 825448da2..2a4637892 100644 --- a/coverage/python/webapp_publisher_snaps_views_py.html +++ b/coverage/python/webapp_publisher_snaps_views_py.html @@ -22,8 +22,8 @@

Coverage for webapp/publisher/snaps/views.py :

Show keyboard shortcuts

- 220 statements   - + 219 statements   +

@@ -115,558 +115,551 @@

61 methods=["GET"], 

62) 

63publisher_snaps.add_url_rule( 

-

64 "/<snap_name>/listing.json", 

-

65 view_func=listing_views.get_listing_snap, 

+

64 "/api/<snap_name>/listing", 

+

65 view_func=listing_views.get_listing_data, 

66 methods=["GET"], 

-

67 defaults={"is_json": True}, 

-

68) 

-

69publisher_snaps.add_url_rule( 

-

70 "/<snap_name>/listing", 

-

71 view_func=listing_views.post_listing_snap, 

-

72 methods=["POST"], 

-

73) 

-

74publisher_snaps.add_url_rule( 

-

75 "/<snap_name>/listing.json", 

-

76 view_func=listing_views.post_listing_snap, 

-

77 methods=["POST"], 

-

78 defaults={"is_json": True}, 

-

79) 

-

80publisher_snaps.add_url_rule( 

-

81 "/<snap_name>/preview", 

-

82 view_func=listing_views.post_preview, 

-

83 methods=["POST"], 

-

84) 

+

67) 

+

68publisher_snaps.add_url_rule( 

+

69 "/api/<snap_name>/listing", 

+

70 view_func=listing_views.post_listing_data, 

+

71 methods=["POST"], 

+

72) 

+

73publisher_snaps.add_url_rule( 

+

74 "/<snap_name>/preview", 

+

75 view_func=listing_views.post_preview, 

+

76 methods=["POST"], 

+

77) 

+

78publisher_snaps.add_url_rule( 

+

79 "/<snap_name>/collaboration", 

+

80 view_func=collaboration_views.get_collaboration_snap, 

+

81 methods=["GET"], 

+

82) 

+

83 

+

84# Build views 

85publisher_snaps.add_url_rule( 

-

86 "/<snap_name>/collaboration", 

-

87 view_func=collaboration_views.get_collaboration_snap, 

+

86 "/<snap_name>/builds", 

+

87 view_func=build_views.get_snap_builds, 

88 methods=["GET"], 

89) 

-

90 

-

91# Build views 

-

92publisher_snaps.add_url_rule( 

-

93 "/<snap_name>/builds", 

-

94 view_func=build_views.get_snap_builds, 

-

95 methods=["GET"], 

-

96) 

-

97publisher_snaps.add_url_rule( 

-

98 "/<snap_name>/builds.json", 

-

99 view_func=build_views.get_snap_builds_json, 

-

100 methods=["GET"], 

-

101) 

-

102publisher_snaps.add_url_rule( 

-

103 "/<snap_name>/builds", 

-

104 view_func=build_views.post_snap_builds, 

-

105 methods=["POST"], 

-

106) 

-

107publisher_snaps.add_url_rule( 

-

108 "/<snap_name>/builds/<build_id>", 

-

109 view_func=build_views.get_snap_build, 

-

110 methods=["GET"], 

-

111) 

-

112publisher_snaps.add_url_rule( 

-

113 "/<snap_name>/builds/validate-repo", 

-

114 view_func=build_views.get_validate_repo, 

-

115 methods=["GET"], 

-

116) 

-

117publisher_snaps.add_url_rule( 

-

118 "/<snap_name>/builds/trigger-build", 

-

119 view_func=build_views.post_build, 

-

120 methods=["POST"], 

-

121) 

-

122publisher_snaps.add_url_rule( 

-

123 "/<snap_name>/builds/check-build-request/<build_id>", 

-

124 view_func=build_views.check_build_request, 

-

125 methods=["GET"], 

-

126) 

-

127publisher_snaps.add_url_rule( 

-

128 "/<snap_name>/webhook/notify", 

-

129 view_func=build_views.post_github_webhook, 

-

130 methods=["POST"], 

-

131) 

-

132# This route is to support previous webhooks from build.snapcraft.io 

-

133publisher_snaps.add_url_rule( 

-

134 "/<github_owner>/<github_repo>/webhook/notify", 

-

135 view_func=build_views.post_github_webhook, 

-

136 methods=["POST"], 

-

137) 

-

138publisher_snaps.add_url_rule( 

-

139 "/<snap_name>/builds/update-webhook", 

-

140 view_func=build_views.get_update_gh_webhooks, 

-

141 methods=["GET"], 

-

142) 

+

90publisher_snaps.add_url_rule( 

+

91 "/<snap_name>/builds.json", 

+

92 view_func=build_views.get_snap_builds_json, 

+

93 methods=["GET"], 

+

94) 

+

95publisher_snaps.add_url_rule( 

+

96 "/<snap_name>/builds", 

+

97 view_func=build_views.post_snap_builds, 

+

98 methods=["POST"], 

+

99) 

+

100publisher_snaps.add_url_rule( 

+

101 "/<snap_name>/builds/<build_id>", 

+

102 view_func=build_views.get_snap_build, 

+

103 methods=["GET"], 

+

104) 

+

105publisher_snaps.add_url_rule( 

+

106 "/<snap_name>/builds/validate-repo", 

+

107 view_func=build_views.get_validate_repo, 

+

108 methods=["GET"], 

+

109) 

+

110publisher_snaps.add_url_rule( 

+

111 "/<snap_name>/builds/trigger-build", 

+

112 view_func=build_views.post_build, 

+

113 methods=["POST"], 

+

114) 

+

115publisher_snaps.add_url_rule( 

+

116 "/<snap_name>/builds/check-build-request/<build_id>", 

+

117 view_func=build_views.check_build_request, 

+

118 methods=["GET"], 

+

119) 

+

120publisher_snaps.add_url_rule( 

+

121 "/<snap_name>/webhook/notify", 

+

122 view_func=build_views.post_github_webhook, 

+

123 methods=["POST"], 

+

124) 

+

125# This route is to support previous webhooks from build.snapcraft.io 

+

126publisher_snaps.add_url_rule( 

+

127 "/<github_owner>/<github_repo>/webhook/notify", 

+

128 view_func=build_views.post_github_webhook, 

+

129 methods=["POST"], 

+

130) 

+

131publisher_snaps.add_url_rule( 

+

132 "/<snap_name>/builds/update-webhook", 

+

133 view_func=build_views.get_update_gh_webhooks, 

+

134 methods=["GET"], 

+

135) 

+

136publisher_snaps.add_url_rule( 

+

137 "/<snap_name>/builds/disconnect/", 

+

138 view_func=build_views.post_disconnect_repo, 

+

139 methods=["POST"], 

+

140) 

+

141 

+

142# Release views 

143publisher_snaps.add_url_rule( 

-

144 "/<snap_name>/builds/disconnect/", 

-

145 view_func=build_views.post_disconnect_repo, 

-

146 methods=["POST"], 

-

147) 

-

148 

-

149# Release views 

-

150publisher_snaps.add_url_rule( 

-

151 "/account/snaps/<snap_name>/release", 

-

152 view_func=release_views.redirect_get_release_history, 

-

153) 

-

154publisher_snaps.add_url_rule( 

-

155 "/<snap_name>/release", 

-

156 view_func=release_views.redirect_get_release_history, 

-

157) 

-

158publisher_snaps.add_url_rule( 

-

159 "/<snap_name>/releases", 

-

160 view_func=release_views.get_release_history, 

-

161 methods=["GET"], 

-

162) 

-

163publisher_snaps.add_url_rule( 

-

164 "/account/snaps/<snap_name>/release", 

-

165 view_func=release_views.redirect_post_release, 

-

166 methods=["POST"], 

-

167) 

-

168publisher_snaps.add_url_rule( 

-

169 "/<snap_name>/release", 

-

170 view_func=release_views.redirect_post_release, 

-

171 methods=["POST"], 

-

172) 

-

173publisher_snaps.add_url_rule( 

-

174 "/<snap_name>/releases/json", 

-

175 view_func=release_views.get_release_history_json, 

-

176) 

-

177publisher_snaps.add_url_rule( 

-

178 "/<snap_name>/releases", 

-

179 view_func=release_views.post_release, 

-

180 methods=["POST"], 

-

181) 

-

182publisher_snaps.add_url_rule( 

-

183 "/<snap_name>/release/close-channel", 

-

184 view_func=release_views.redirect_post_close_channel, 

-

185 methods=["POST"], 

-

186) 

-

187publisher_snaps.add_url_rule( 

-

188 "/<snap_name>/releases/close-channel", 

-

189 view_func=release_views.post_close_channel, 

-

190 methods=["POST"], 

-

191) 

-

192publisher_snaps.add_url_rule( 

-

193 "/<snap_name>/releases/default-track", 

-

194 view_func=release_views.post_default_track, 

-

195 methods=["POST"], 

-

196) 

-

197publisher_snaps.add_url_rule( 

-

198 "/<snap_name>/releases/revision/<revision>", 

-

199 view_func=release_views.get_snap_revision_json, 

+

144 "/account/snaps/<snap_name>/release", 

+

145 view_func=release_views.redirect_get_release_history, 

+

146) 

+

147publisher_snaps.add_url_rule( 

+

148 "/<snap_name>/release", 

+

149 view_func=release_views.redirect_get_release_history, 

+

150) 

+

151publisher_snaps.add_url_rule( 

+

152 "/<snap_name>/releases", 

+

153 view_func=release_views.get_release_history, 

+

154 methods=["GET"], 

+

155) 

+

156publisher_snaps.add_url_rule( 

+

157 "/account/snaps/<snap_name>/release", 

+

158 view_func=release_views.redirect_post_release, 

+

159 methods=["POST"], 

+

160) 

+

161publisher_snaps.add_url_rule( 

+

162 "/<snap_name>/release", 

+

163 view_func=release_views.redirect_post_release, 

+

164 methods=["POST"], 

+

165) 

+

166publisher_snaps.add_url_rule( 

+

167 "/<snap_name>/releases/json", 

+

168 view_func=release_views.get_release_history_json, 

+

169) 

+

170publisher_snaps.add_url_rule( 

+

171 "/<snap_name>/releases", 

+

172 view_func=release_views.post_release, 

+

173 methods=["POST"], 

+

174) 

+

175publisher_snaps.add_url_rule( 

+

176 "/<snap_name>/release/close-channel", 

+

177 view_func=release_views.redirect_post_close_channel, 

+

178 methods=["POST"], 

+

179) 

+

180publisher_snaps.add_url_rule( 

+

181 "/<snap_name>/releases/close-channel", 

+

182 view_func=release_views.post_close_channel, 

+

183 methods=["POST"], 

+

184) 

+

185publisher_snaps.add_url_rule( 

+

186 "/<snap_name>/releases/default-track", 

+

187 view_func=release_views.post_default_track, 

+

188 methods=["POST"], 

+

189) 

+

190publisher_snaps.add_url_rule( 

+

191 "/<snap_name>/releases/revision/<revision>", 

+

192 view_func=release_views.get_snap_revision_json, 

+

193) 

+

194 

+

195# Metrics views 

+

196publisher_snaps.add_url_rule( 

+

197 "/snaps/metrics/json", 

+

198 view_func=metrics_views.get_account_snaps_metrics, 

+

199 methods=["POST"], 

200) 

-

201 

-

202# Metrics views 

-

203publisher_snaps.add_url_rule( 

-

204 "/snaps/metrics/json", 

-

205 view_func=metrics_views.get_account_snaps_metrics, 

-

206 methods=["POST"], 

-

207) 

-

208publisher_snaps.add_url_rule( 

-

209 "/account/snaps/<snap_name>/measure", 

-

210 view_func=metrics_views.get_measure_snap, 

-

211) 

-

212publisher_snaps.add_url_rule( 

-

213 "/account/snaps/<snap_name>/metrics", 

-

214 view_func=metrics_views.get_measure_snap, 

-

215) 

-

216publisher_snaps.add_url_rule( 

-

217 "/<snap_name>/metrics", 

-

218 view_func=metrics_views.publisher_snap_metrics, 

-

219) 

-

220 

-

221# Publice views 

-

222publisher_snaps.add_url_rule( 

-

223 "/<snap_name>/publicise", 

-

224 view_func=publicise_views.get_publicise, 

-

225) 

-

226publisher_snaps.add_url_rule( 

-

227 "/<snap_name>/publicise/badges", 

-

228 view_func=publicise_views.get_publicise_badges, 

-

229) 

-

230publisher_snaps.add_url_rule( 

-

231 "/<snap_name>/publicise/cards", 

-

232 view_func=publicise_views.get_publicise_cards, 

-

233) 

-

234 

-

235# Settings views 

-

236publisher_snaps.add_url_rule( 

-

237 "/<snap_name>/settings", 

-

238 view_func=settings_views.get_settings, 

-

239) 

-

240publisher_snaps.add_url_rule( 

-

241 "/<snap_name>/settings.json", 

-

242 view_func=settings_views.get_settings_json, 

-

243) 

-

244publisher_snaps.add_url_rule( 

-

245 "/<snap_name>/settings", 

-

246 view_func=settings_views.post_settings, 

-

247 methods=["POST"], 

-

248) 

-

249publisher_snaps.add_url_rule( 

-

250 "/<snap_name>/settings.json", 

-

251 view_func=settings_views.post_settings_json, 

-

252 methods=["POST"], 

-

253) 

+

201publisher_snaps.add_url_rule( 

+

202 "/account/snaps/<snap_name>/measure", 

+

203 view_func=metrics_views.get_measure_snap, 

+

204) 

+

205publisher_snaps.add_url_rule( 

+

206 "/account/snaps/<snap_name>/metrics", 

+

207 view_func=metrics_views.get_measure_snap, 

+

208) 

+

209publisher_snaps.add_url_rule( 

+

210 "/<snap_name>/metrics", 

+

211 view_func=metrics_views.publisher_snap_metrics, 

+

212) 

+

213 

+

214# Publice views 

+

215publisher_snaps.add_url_rule( 

+

216 "/<snap_name>/publicise", 

+

217 view_func=publicise_views.get_publicise, 

+

218) 

+

219publisher_snaps.add_url_rule( 

+

220 "/<snap_name>/publicise/badges", 

+

221 view_func=publicise_views.get_publicise_badges, 

+

222) 

+

223publisher_snaps.add_url_rule( 

+

224 "/<snap_name>/publicise/cards", 

+

225 view_func=publicise_views.get_publicise_cards, 

+

226) 

+

227 

+

228# Settings views 

+

229publisher_snaps.add_url_rule( 

+

230 "/<snap_name>/settings", 

+

231 view_func=settings_views.get_settings, 

+

232) 

+

233publisher_snaps.add_url_rule( 

+

234 "/<snap_name>/settings.json", 

+

235 view_func=settings_views.get_settings_json, 

+

236) 

+

237publisher_snaps.add_url_rule( 

+

238 "/<snap_name>/settings", 

+

239 view_func=settings_views.post_settings, 

+

240 methods=["POST"], 

+

241) 

+

242publisher_snaps.add_url_rule( 

+

243 "/<snap_name>/settings.json", 

+

244 view_func=settings_views.post_settings_json, 

+

245 methods=["POST"], 

+

246) 

+

247 

+

248 

+

249@publisher_snaps.route("/account/snaps") 

+

250@login_required 

+

251def redirect_get_account_snaps(): 

+

252 return flask.redirect(flask.url_for(".get_account_snaps")) 

+

253 

254 

-

255 

-

256@publisher_snaps.route("/account/snaps") 

-

257@login_required 

-

258def redirect_get_account_snaps(): 

-

259 return flask.redirect(flask.url_for(".get_account_snaps")) 

-

260 

+

255@publisher_snaps.route("/snaps") 

+

256@login_required 

+

257def get_account_snaps(): 

+

258 account_info = publisher_api.get_account(flask.session) 

+

259 

+

260 user_snaps, registered_snaps = logic.get_snaps_account_info(account_info) 

261 

-

262@publisher_snaps.route("/snaps") 

-

263@login_required 

-

264def get_account_snaps(): 

-

265 account_info = publisher_api.get_account(flask.session) 

-

266 

-

267 user_snaps, registered_snaps = logic.get_snaps_account_info(account_info) 

+

262 flask_user = flask.session["publisher"] 

+

263 

+

264 is_users_snap = { 

+

265 snap_name: get_is_user_snap(snap_name) 

+

266 for snap_name in registered_snaps 

+

267 } 

268 

-

269 flask_user = flask.session["publisher"] 

-

270 

-

271 is_users_snap = { 

-

272 snap_name: get_is_user_snap(snap_name) 

-

273 for snap_name in registered_snaps 

+

269 context = { 

+

270 "snaps": user_snaps, 

+

271 "current_user": flask_user["nickname"], 

+

272 "registered_snaps": registered_snaps, 

+

273 "is_users_snap": is_users_snap, 

274 } 

275 

-

276 context = { 

-

277 "snaps": user_snaps, 

-

278 "current_user": flask_user["nickname"], 

-

279 "registered_snaps": registered_snaps, 

-

280 "is_users_snap": is_users_snap, 

-

281 } 

-

282 

-

283 return flask.render_template("publisher/account-snaps.html", **context) 

-

284 

-

285 

-

286@publisher_snaps.route("/snap-builds.json") 

-

287@login_required 

-

288def get_snap_build_status(): 

-

289 try: 

-

290 account_info = publisher_api.get_account(flask.session) 

-

291 except (StoreApiError, ApiError) as api_error: 

-

292 return flask.jsonify(api_error), 400 

+

276 return flask.render_template("publisher/account-snaps.html", **context) 

+

277 

+

278 

+

279@publisher_snaps.route("/snap-builds.json") 

+

280@login_required 

+

281def get_snap_build_status(): 

+

282 try: 

+

283 account_info = publisher_api.get_account(flask.session) 

+

284 except (StoreApiError, ApiError) as api_error: 

+

285 return flask.jsonify(api_error), 400 

+

286 

+

287 response = [] 

+

288 user_snaps, _ = logic.get_snaps_account_info(account_info) 

+

289 

+

290 for snap_name in user_snaps: 

+

291 snap_build_statuses = launchpad.get_snap_build_status(snap_name) 

+

292 status = map_snap_build_status(snap_build_statuses) 

293 

-

294 response = [] 

-

295 user_snaps, _ = logic.get_snaps_account_info(account_info) 

-

296 

-

297 for snap_name in user_snaps: 

-

298 snap_build_statuses = launchpad.get_snap_build_status(snap_name) 

-

299 status = map_snap_build_status(snap_build_statuses) 

-

300 

-

301 response.append({"name": snap_name, "status": status}) 

+

294 response.append({"name": snap_name, "status": status}) 

+

295 

+

296 return flask.jsonify(response) 

+

297 

+

298 

+

299@publisher_snaps.route("/account/register-snap") 

+

300def redirect_get_register_name(): 

+

301 return flask.redirect(flask.url_for(".get_register_name")) 

302 

-

303 return flask.jsonify(response) 

-

304 

-

305 

-

306@publisher_snaps.route("/account/register-snap") 

-

307def redirect_get_register_name(): 

-

308 return flask.redirect(flask.url_for(".get_register_name")) 

-

309 

+

303 

+

304@publisher_snaps.route("/register-snap") 

+

305@login_required 

+

306def get_register_name(): 

+

307 stores = admin_api.get_stores(flask.session) 

+

308 

+

309 available_stores = logic.filter_available_stores(stores) 

310 

-

311@publisher_snaps.route("/register-snap") 

-

312@login_required 

-

313def get_register_name(): 

-

314 stores = admin_api.get_stores(flask.session) 

-

315 

-

316 available_stores = logic.filter_available_stores(stores) 

-

317 

-

318 snap_name = flask.request.args.get("snap_name", default="", type=str) 

-

319 store = flask.request.args.get("store", default="", type=str) 

-

320 

-

321 conflict_str = flask.request.args.get( 

-

322 "conflict", default="False", type=str 

-

323 ) 

-

324 conflict = conflict_str == "True" 

-

325 

-

326 already_owned_str = flask.request.args.get( 

-

327 "already_owned", default="False", type=str 

-

328 ) 

-

329 already_owned = already_owned_str == "True" 

-

330 

-

331 reserved_str = flask.request.args.get( 

-

332 "reserved", default="False", type=str 

-

333 ) 

-

334 reserved = reserved_str == "True" 

-

335 

-

336 is_private_str = flask.request.args.get( 

-

337 "is_private", default="False", type=str 

-

338 ) 

-

339 is_private = is_private_str == "True" 

-

340 

-

341 context = { 

-

342 "snap_name": snap_name, 

-

343 "is_private": is_private, 

-

344 "conflict": conflict, 

-

345 "already_owned": already_owned, 

-

346 "reserved": reserved, 

-

347 "store": store, 

-

348 "available_stores": available_stores, 

-

349 } 

-

350 return flask.render_template("publisher/register-snap.html", **context) 

-

351 

-

352 

-

353@publisher_snaps.route("/account/register-snap", methods=["POST"]) 

-

354def redirect_post_register_name(): 

-

355 return flask.redirect(flask.url_for(".post_register_name"), 307) 

-

356 

-

357 

-

358@publisher_snaps.route("/register-snap", methods=["POST"]) 

-

359@login_required 

-

360def post_register_name(): 

-

361 snap_name = flask.request.form.get("snap-name") 

+

311 snap_name = flask.request.args.get("snap_name", default="", type=str) 

+

312 store = flask.request.args.get("store", default="", type=str) 

+

313 

+

314 conflict_str = flask.request.args.get( 

+

315 "conflict", default="False", type=str 

+

316 ) 

+

317 conflict = conflict_str == "True" 

+

318 

+

319 already_owned_str = flask.request.args.get( 

+

320 "already_owned", default="False", type=str 

+

321 ) 

+

322 already_owned = already_owned_str == "True" 

+

323 

+

324 reserved_str = flask.request.args.get( 

+

325 "reserved", default="False", type=str 

+

326 ) 

+

327 reserved = reserved_str == "True" 

+

328 

+

329 is_private_str = flask.request.args.get( 

+

330 "is_private", default="False", type=str 

+

331 ) 

+

332 is_private = is_private_str == "True" 

+

333 

+

334 context = { 

+

335 "snap_name": snap_name, 

+

336 "is_private": is_private, 

+

337 "conflict": conflict, 

+

338 "already_owned": already_owned, 

+

339 "reserved": reserved, 

+

340 "store": store, 

+

341 "available_stores": available_stores, 

+

342 } 

+

343 return flask.render_template("publisher/register-snap.html", **context) 

+

344 

+

345 

+

346@publisher_snaps.route("/account/register-snap", methods=["POST"]) 

+

347def redirect_post_register_name(): 

+

348 return flask.redirect(flask.url_for(".post_register_name"), 307) 

+

349 

+

350 

+

351@publisher_snaps.route("/register-snap", methods=["POST"]) 

+

352@login_required 

+

353def post_register_name(): 

+

354 snap_name = flask.request.form.get("snap-name") 

+

355 

+

356 if not snap_name: 

+

357 return flask.redirect(flask.url_for(".get_register_name")) 

+

358 

+

359 is_private = flask.request.form.get("is_private") == "private" 

+

360 store = flask.request.form.get("store") 

+

361 registrant_comment = flask.request.form.get("registrant_comment") 

362 

-

363 if not snap_name: 

-

364 return flask.redirect(flask.url_for(".get_register_name")) 

-

365 

-

366 is_private = flask.request.form.get("is_private") == "private" 

-

367 store = flask.request.form.get("store") 

-

368 registrant_comment = flask.request.form.get("registrant_comment") 

-

369 

-

370 try: 

-

371 publisher_api.post_register_name( 

-

372 session=flask.session, 

-

373 snap_name=snap_name, 

-

374 is_private=is_private, 

-

375 store=store, 

-

376 registrant_comment=registrant_comment, 

-

377 ) 

-

378 except StoreApiResponseErrorList as api_response_error_list: 

-

379 stores = admin_api.get_stores(flask.session) 

-

380 

-

381 available_stores = logic.filter_available_stores(stores) 

-

382 

-

383 if api_response_error_list.status_code == 409: 

-

384 for error in api_response_error_list.errors: 

-

385 if error["code"] == "already_claimed": 

-

386 return flask.redirect("/admin/account") 

-

387 elif error["code"] == "already_registered": 

-

388 return flask.redirect( 

-

389 flask.url_for( 

-

390 ".get_register_name", 

-

391 snap_name=snap_name, 

-

392 is_private=is_private, 

-

393 store=store, 

-

394 conflict=True, 

-

395 ) 

-

396 ) 

-

397 elif error["code"] == "already_owned": 

-

398 return flask.redirect( 

-

399 flask.url_for( 

-

400 ".get_register_name", 

-

401 snap_name=snap_name, 

-

402 is_private=is_private, 

-

403 store=store, 

-

404 already_owned=True, 

-

405 ) 

-

406 ) 

-

407 elif error["code"] == "reserved_name": 

-

408 return flask.redirect( 

-

409 flask.url_for( 

-

410 ".get_register_name", 

-

411 snap_name=snap_name, 

-

412 is_private=is_private, 

-

413 store=store, 

-

414 reserved=True, 

-

415 ) 

-

416 ) 

-

417 elif error["code"] == "name-review-required": 

-

418 formatted_error = re.sub( 

-

419 r"(https?://\S+)", 

-

420 r'<a href="\1">\1</a>', 

-

421 error["message"], 

-

422 ) 

-

423 error["message"] = formatted_error 

+

363 try: 

+

364 publisher_api.post_register_name( 

+

365 session=flask.session, 

+

366 snap_name=snap_name, 

+

367 is_private=is_private, 

+

368 store=store, 

+

369 registrant_comment=registrant_comment, 

+

370 ) 

+

371 except StoreApiResponseErrorList as api_response_error_list: 

+

372 stores = admin_api.get_stores(flask.session) 

+

373 

+

374 available_stores = logic.filter_available_stores(stores) 

+

375 

+

376 if api_response_error_list.status_code == 409: 

+

377 for error in api_response_error_list.errors: 

+

378 if error["code"] == "already_claimed": 

+

379 return flask.redirect("/admin/account") 

+

380 elif error["code"] == "already_registered": 

+

381 return flask.redirect( 

+

382 flask.url_for( 

+

383 ".get_register_name", 

+

384 snap_name=snap_name, 

+

385 is_private=is_private, 

+

386 store=store, 

+

387 conflict=True, 

+

388 ) 

+

389 ) 

+

390 elif error["code"] == "already_owned": 

+

391 return flask.redirect( 

+

392 flask.url_for( 

+

393 ".get_register_name", 

+

394 snap_name=snap_name, 

+

395 is_private=is_private, 

+

396 store=store, 

+

397 already_owned=True, 

+

398 ) 

+

399 ) 

+

400 elif error["code"] == "reserved_name": 

+

401 return flask.redirect( 

+

402 flask.url_for( 

+

403 ".get_register_name", 

+

404 snap_name=snap_name, 

+

405 is_private=is_private, 

+

406 store=store, 

+

407 reserved=True, 

+

408 ) 

+

409 ) 

+

410 elif error["code"] == "name-review-required": 

+

411 formatted_error = re.sub( 

+

412 r"(https?://\S+)", 

+

413 r'<a href="\1">\1</a>', 

+

414 error["message"], 

+

415 ) 

+

416 error["message"] = formatted_error 

+

417 

+

418 context = { 

+

419 "snap_name": snap_name, 

+

420 "is_private": is_private, 

+

421 "available_stores": available_stores, 

+

422 "errors": api_response_error_list.errors, 

+

423 } 

424 

-

425 context = { 

-

426 "snap_name": snap_name, 

-

427 "is_private": is_private, 

-

428 "available_stores": available_stores, 

-

429 "errors": api_response_error_list.errors, 

-

430 } 

-

431 

-

432 return flask.render_template("publisher/register-snap.html", **context) 

-

433 

-

434 flask.flash( 

-

435 "".join( 

-

436 [ 

-

437 snap_name, 

-

438 " registered.", 

-

439 ' <a href="https://docs.snapcraft.io/build-snaps/upload"', 

-

440 " ", 

-

441 ' target="blank">How to upload a Snap</a>', 

-

442 ] 

-

443 ) 

-

444 ) 

-

445 

-

446 return flask.redirect(flask.url_for("account.get_account")) 

-

447 

-

448 

-

449@publisher_snaps.route("/api/packages/<snap_name>", methods=["GET"]) 

-

450@login_required 

-

451@exchange_required 

-

452def get_package_metadata(snap_name): 

-

453 package_metadata = publisher_api.get_package_metadata( 

-

454 flask.session, "snap", snap_name 

-

455 ) 

-

456 if "metadata" in package_metadata and package_metadata["metadata"]: 

-

457 return jsonify({"data": package_metadata["metadata"], "success": True}) 

-

458 else: 

-

459 return ( 

-

460 jsonify({"error": "Package metadata not found", "success": False}), 

-

461 404, 

-

462 ) 

-

463 

-

464 

-

465@publisher_snaps.route("/packages/<package_name>", methods=["DELETE"]) 

-

466@login_required 

-

467@exchange_required 

-

468def delete_package(package_name): 

-

469 response = publisher_api.unregister_package_name( 

-

470 flask.session, package_name 

+

425 return flask.render_template("publisher/register-snap.html", **context) 

+

426 

+

427 flask.flash( 

+

428 "".join( 

+

429 [ 

+

430 snap_name, 

+

431 " registered.", 

+

432 ' <a href="https://docs.snapcraft.io/build-snaps/upload"', 

+

433 " ", 

+

434 ' target="blank">How to upload a Snap</a>', 

+

435 ] 

+

436 ) 

+

437 ) 

+

438 

+

439 return flask.redirect(flask.url_for("account.get_account")) 

+

440 

+

441 

+

442@publisher_snaps.route("/api/packages/<snap_name>", methods=["GET"]) 

+

443@login_required 

+

444@exchange_required 

+

445def get_package_metadata(snap_name): 

+

446 package_metadata = publisher_api.get_package_metadata( 

+

447 flask.session, "snap", snap_name 

+

448 ) 

+

449 if "metadata" in package_metadata and package_metadata["metadata"]: 

+

450 return jsonify({"data": package_metadata["metadata"], "success": True}) 

+

451 else: 

+

452 return ( 

+

453 jsonify({"error": "Package metadata not found", "success": False}), 

+

454 404, 

+

455 ) 

+

456 

+

457 

+

458@publisher_snaps.route("/packages/<package_name>", methods=["DELETE"]) 

+

459@login_required 

+

460@exchange_required 

+

461def delete_package(package_name): 

+

462 response = publisher_api.unregister_package_name( 

+

463 flask.session, package_name 

+

464 ) 

+

465 

+

466 if response.status_code == 200: 

+

467 return ("", 200) 

+

468 return ( 

+

469 jsonify({"error": response.json()["error-list"][0]["message"]}), 

+

470 response.status_code, 

471 ) 

472 

-

473 if response.status_code == 200: 

-

474 return ("", 200) 

-

475 return ( 

-

476 jsonify({"error": response.json()["error-list"][0]["message"]}), 

-

477 response.status_code, 

-

478 ) 

-

479 

-

480 

-

481@publisher_snaps.route("/snap_info/user_snap/<snap_name>", methods=["GET"]) 

-

482@login_required 

-

483def get_is_user_snap(snap_name): 

-

484 is_users_snap = False 

-

485 try: 

-

486 snap_info = publisher_api.get_snap_info(snap_name, flask.session) 

-

487 except (StoreApiError, ApiError) as api_error: 

-

488 return flask.jsonify({"error": str(api_error)}), 400 

-

489 

-

490 if authentication.is_authenticated(flask.session): 

-

491 publisher_info = flask.session.get("publisher", {}) 

-

492 if ( 

-

493 publisher_info.get("nickname") 

-

494 == snap_info["publisher"]["username"] 

-

495 ): 

-

496 is_users_snap = True 

-

497 

-

498 return {"is_users_snap": is_users_snap} 

-

499 

-

500 

-

501@publisher_snaps.route("/register-snap/json", methods=["POST"]) 

-

502@login_required 

-

503def post_register_name_json(): 

-

504 snap_name = flask.request.form.get("snap-name") 

-

505 

-

506 if not snap_name: 

-

507 return ( 

-

508 flask.jsonify({"errors": [{"message": "Snap name is required"}]}), 

-

509 400, 

-

510 ) 

-

511 

-

512 try: 

-

513 response = publisher_api.post_register_name( 

-

514 session=flask.session, snap_name=snap_name 

-

515 ) 

-

516 except StoreApiResponseErrorList as api_response_error_list: 

-

517 for error in api_response_error_list.errors: 

-

518 # if snap name is already owned treat it as success 

-

519 if error["code"] == "already_owned": 

-

520 return flask.jsonify( 

-

521 {"code": error["code"], "snap_name": snap_name} 

-

522 ) 

-

523 return ( 

-

524 flask.jsonify({"errors": api_response_error_list.errors}), 

-

525 api_response_error_list.status_code, 

-

526 ) 

-

527 

-

528 response["code"] = "created" 

-

529 

-

530 return flask.jsonify(response) 

-

531 

-

532 

-

533@publisher_snaps.route("/register-name-dispute") 

-

534@login_required 

-

535def get_register_name_dispute(): 

-

536 stores = admin_api.get_stores(flask.session) 

-

537 

-

538 snap_name = flask.request.args.get("snap-name") 

-

539 store_id = flask.request.args.get("store") 

-

540 store_name = logic.get_store_name(store_id, stores) 

-

541 

-

542 if not snap_name: 

-

543 return flask.redirect( 

-

544 flask.url_for(".get_register_name", snap_name=snap_name) 

-

545 ) 

-

546 return flask.render_template( 

-

547 "publisher/register-name-dispute.html", 

-

548 snap_name=snap_name, 

-

549 store=store_name, 

-

550 ) 

-

551 

-

552 

-

553@publisher_snaps.route("/register-name-dispute", methods=["POST"]) 

-

554@login_required 

-

555def post_register_name_dispute(): 

-

556 try: 

-

557 snap_name = flask.request.form.get("snap-name", "") 

-

558 claim_comment = flask.request.form.get("claim-comment", "") 

-

559 publisher_api.post_register_name_dispute( 

-

560 flask.session, 

-

561 bleach.clean(snap_name), 

-

562 bleach.clean(claim_comment), 

-

563 ) 

-

564 except StoreApiResponseErrorList as api_response_error_list: 

-

565 if api_response_error_list.status_code in [400, 409]: 

-

566 return flask.render_template( 

-

567 "publisher/register-name-dispute.html", 

-

568 snap_name=snap_name, 

-

569 errors=api_response_error_list.errors, 

-

570 ) 

-

571 

-

572 return flask.render_template( 

-

573 "publisher/register-name-dispute-success.html", 

-

574 snap_name=snap_name, 

-

575 ) 

-

576 

-

577 

-

578@publisher_snaps.route("/request-reserved-name") 

-

579@login_required 

-

580def get_request_reserved_name(): 

-

581 stores = admin_api.get_stores(flask.session) 

-

582 

-

583 snap_name = flask.request.args.get("snap_name") 

-

584 store_id = flask.request.args.get("store") 

-

585 store_name = logic.get_store_name(store_id, stores) 

-

586 

-

587 if not snap_name: 

-

588 return flask.redirect( 

-

589 flask.url_for( 

-

590 ".get_register_name", snap_name=snap_name, store=store_id 

-

591 ) 

-

592 ) 

-

593 return flask.render_template( 

-

594 "publisher/request-reserved-name.html", 

-

595 snap_name=snap_name, 

-

596 store=store_name, 

-

597 ) 

-

598 

+

473 

+

474@publisher_snaps.route("/snap_info/user_snap/<snap_name>", methods=["GET"]) 

+

475@login_required 

+

476def get_is_user_snap(snap_name): 

+

477 is_users_snap = False 

+

478 try: 

+

479 snap_info = publisher_api.get_snap_info(snap_name, flask.session) 

+

480 except (StoreApiError, ApiError) as api_error: 

+

481 return flask.jsonify({"error": str(api_error)}), 400 

+

482 

+

483 if authentication.is_authenticated(flask.session): 

+

484 publisher_info = flask.session.get("publisher", {}) 

+

485 if ( 

+

486 publisher_info.get("nickname") 

+

487 == snap_info["publisher"]["username"] 

+

488 ): 

+

489 is_users_snap = True 

+

490 

+

491 return {"is_users_snap": is_users_snap} 

+

492 

+

493 

+

494@publisher_snaps.route("/register-snap/json", methods=["POST"]) 

+

495@login_required 

+

496def post_register_name_json(): 

+

497 snap_name = flask.request.form.get("snap-name") 

+

498 

+

499 if not snap_name: 

+

500 return ( 

+

501 flask.jsonify({"errors": [{"message": "Snap name is required"}]}), 

+

502 400, 

+

503 ) 

+

504 

+

505 try: 

+

506 response = publisher_api.post_register_name( 

+

507 session=flask.session, snap_name=snap_name 

+

508 ) 

+

509 except StoreApiResponseErrorList as api_response_error_list: 

+

510 for error in api_response_error_list.errors: 

+

511 # if snap name is already owned treat it as success 

+

512 if error["code"] == "already_owned": 

+

513 return flask.jsonify( 

+

514 {"code": error["code"], "snap_name": snap_name} 

+

515 ) 

+

516 return ( 

+

517 flask.jsonify({"errors": api_response_error_list.errors}), 

+

518 api_response_error_list.status_code, 

+

519 ) 

+

520 

+

521 response["code"] = "created" 

+

522 

+

523 return flask.jsonify(response) 

+

524 

+

525 

+

526@publisher_snaps.route("/register-name-dispute") 

+

527@login_required 

+

528def get_register_name_dispute(): 

+

529 stores = admin_api.get_stores(flask.session) 

+

530 

+

531 snap_name = flask.request.args.get("snap-name") 

+

532 store_id = flask.request.args.get("store") 

+

533 store_name = logic.get_store_name(store_id, stores) 

+

534 

+

535 if not snap_name: 

+

536 return flask.redirect( 

+

537 flask.url_for(".get_register_name", snap_name=snap_name) 

+

538 ) 

+

539 return flask.render_template( 

+

540 "publisher/register-name-dispute.html", 

+

541 snap_name=snap_name, 

+

542 store=store_name, 

+

543 ) 

+

544 

+

545 

+

546@publisher_snaps.route("/register-name-dispute", methods=["POST"]) 

+

547@login_required 

+

548def post_register_name_dispute(): 

+

549 try: 

+

550 snap_name = flask.request.form.get("snap-name", "") 

+

551 claim_comment = flask.request.form.get("claim-comment", "") 

+

552 publisher_api.post_register_name_dispute( 

+

553 flask.session, 

+

554 bleach.clean(snap_name), 

+

555 bleach.clean(claim_comment), 

+

556 ) 

+

557 except StoreApiResponseErrorList as api_response_error_list: 

+

558 if api_response_error_list.status_code in [400, 409]: 

+

559 return flask.render_template( 

+

560 "publisher/register-name-dispute.html", 

+

561 snap_name=snap_name, 

+

562 errors=api_response_error_list.errors, 

+

563 ) 

+

564 

+

565 return flask.render_template( 

+

566 "publisher/register-name-dispute-success.html", 

+

567 snap_name=snap_name, 

+

568 ) 

+

569 

+

570 

+

571@publisher_snaps.route("/request-reserved-name") 

+

572@login_required 

+

573def get_request_reserved_name(): 

+

574 stores = admin_api.get_stores(flask.session) 

+

575 

+

576 snap_name = flask.request.args.get("snap_name") 

+

577 store_id = flask.request.args.get("store") 

+

578 store_name = logic.get_store_name(store_id, stores) 

+

579 

+

580 if not snap_name: 

+

581 return flask.redirect( 

+

582 flask.url_for( 

+

583 ".get_register_name", snap_name=snap_name, store=store_id 

+

584 ) 

+

585 ) 

+

586 return flask.render_template( 

+

587 "publisher/request-reserved-name.html", 

+

588 snap_name=snap_name, 

+

589 store=store_name, 

+

590 ) 

+

591 

+

592 

+

593@publisher_snaps.route("/snaps/api/snap-count") 

+

594@login_required 

+

595def snap_count(): 

+

596 account_info = publisher_api.get_account(flask.session) 

+

597 

+

598 user_snaps, registered_snaps = logic.get_snaps_account_info(account_info) 

599 

-

600@publisher_snaps.route("/snaps/api/snap-count") 

-

601@login_required 

-

602def snap_count(): 

-

603 account_info = publisher_api.get_account(flask.session) 

-

604 

-

605 user_snaps, registered_snaps = logic.get_snaps_account_info(account_info) 

-

606 

-

607 context = {"count": len(user_snaps), "snaps": list(user_snaps.keys())} 

-

608 

-

609 return flask.jsonify(context) 

+

600 context = {"count": len(user_snaps), "snaps": list(user_snaps.keys())} 

+

601 

+

602 return flask.jsonify(context) 

diff --git a/coverage/python/webapp_publisher_views_py.html b/coverage/python/webapp_publisher_views_py.html index 881d2e78d..f763d1d6e 100644 --- a/coverage/python/webapp_publisher_views_py.html +++ b/coverage/python/webapp_publisher_views_py.html @@ -157,7 +157,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_snapcraft_logic_py.html b/coverage/python/webapp_snapcraft_logic_py.html index a6cc81352..f811d6272 100644 --- a/coverage/python/webapp_snapcraft_logic_py.html +++ b/coverage/python/webapp_snapcraft_logic_py.html @@ -95,7 +95,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_snapcraft_views_py.html b/coverage/python/webapp_snapcraft_views_py.html index cae21cf23..99fd84cab 100644 --- a/coverage/python/webapp_snapcraft_views_py.html +++ b/coverage/python/webapp_snapcraft_views_py.html @@ -571,7 +571,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_store___init___py.html b/coverage/python/webapp_store___init___py.html index 8dd5600e2..2b6ea5fcd 100644 --- a/coverage/python/webapp_store___init___py.html +++ b/coverage/python/webapp_store___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_store_logic_py.html b/coverage/python/webapp_store_logic_py.html index 2240b2c01..636da45d6 100644 --- a/coverage/python/webapp_store_logic_py.html +++ b/coverage/python/webapp_store_logic_py.html @@ -560,7 +560,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_store_snap_details_views_py.html b/coverage/python/webapp_store_snap_details_views_py.html index 1c68f6638..b1eeb6ca6 100644 --- a/coverage/python/webapp_store_snap_details_views_py.html +++ b/coverage/python/webapp_store_snap_details_views_py.html @@ -527,7 +527,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_store_views_py.html b/coverage/python/webapp_store_views_py.html index 27501c5a5..e24ab1cb1 100644 --- a/coverage/python/webapp_store_views_py.html +++ b/coverage/python/webapp_store_views_py.html @@ -505,7 +505,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_template_utils_py.html b/coverage/python/webapp_template_utils_py.html index 58169f2e2..56003c2f4 100644 --- a/coverage/python/webapp_template_utils_py.html +++ b/coverage/python/webapp_template_utils_py.html @@ -241,7 +241,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_tutorials___init___py.html b/coverage/python/webapp_tutorials___init___py.html index 86d57a3b0..7f03cf5cc 100644 --- a/coverage/python/webapp_tutorials___init___py.html +++ b/coverage/python/webapp_tutorials___init___py.html @@ -57,7 +57,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000

diff --git a/coverage/python/webapp_tutorials_views_py.html b/coverage/python/webapp_tutorials_views_py.html index ca13686c5..20e3d5399 100644 --- a/coverage/python/webapp_tutorials_views_py.html +++ b/coverage/python/webapp_tutorials_views_py.html @@ -130,7 +130,7 @@

« index     coverage.py v5.5, - created at 2024-10-01 22:06 +0000 + created at 2024-10-02 22:06 +0000