From 646ea3214a2498b81a24b85a2ac26ab2bdd94e4a Mon Sep 17 00:00:00 2001 From: Antek Grzanka Date: Thu, 28 Apr 2016 16:46:00 +0300 Subject: [PATCH] Add Taiga integration. --- changelog.md | 2 +- static/images/integrations/logos/taiga.png | Bin 0 -> 9074 bytes static/images/integrations/taiga/001.png | Bin 0 -> 15819 bytes templates/zerver/integrations.html | 88 +++++++ .../taiga/taiga_issue_changed_assigned.json | 70 +++++ .../taiga_issue_changed_comment_added.json | 62 +++++ .../taiga_issue_changed_description.json | 72 +++++ .../taiga/taiga_issue_changed_priority.json | 68 +++++ .../taiga/taiga_issue_changed_reassigned.json | 71 +++++ .../taiga/taiga_issue_changed_severity.json | 68 +++++ .../taiga/taiga_issue_changed_status.json | 68 +++++ .../taiga/taiga_issue_changed_subject.json | 68 +++++ .../taiga/taiga_issue_changed_type.json | 68 +++++ .../fixtures/taiga/taiga_issue_created.json | 39 +++ .../fixtures/taiga/taiga_issue_deleted.json | 38 +++ .../taiga/taiga_milestone_changed_name.json | 54 ++++ .../taiga/taiga_milestone_changed_time.json | 50 ++++ .../taiga/taiga_milestone_created.json | 20 ++ .../taiga/taiga_milestone_deleted.json | 21 ++ .../taiga/taiga_task_changed_assigned.json | 71 +++++ .../taiga/taiga_task_changed_blocked.json | 74 ++++++ .../taiga_task_changed_comment_added.json | 66 +++++ .../taiga/taiga_task_changed_description.json | 70 +++++ .../taiga/taiga_task_changed_reassigned.json | 72 +++++ .../taiga/taiga_task_changed_status.json | 72 +++++ .../taiga/taiga_task_changed_subject.json | 66 +++++ .../taiga/taiga_task_changed_unblocked.json | 74 ++++++ .../fixtures/taiga/taiga_task_changed_us.json | 73 ++++++ zerver/fixtures/taiga/taiga_task_created.json | 43 +++ zerver/fixtures/taiga/taiga_task_deleted.json | 39 +++ .../taiga_userstory_changed_assigned.json | 94 +++++++ .../taiga_userstory_changed_blocked.json | 100 +++++++ .../taiga/taiga_userstory_changed_closed.json | 103 ++++++++ ...taiga_userstory_changed_comment_added.json | 86 ++++++ .../taiga_userstory_changed_description.json | 96 +++++++ .../taiga_userstory_changed_milestone.json | 95 +++++++ ...taiga_userstory_changed_new_milestone.json | 94 +++++++ .../taiga/taiga_userstory_changed_points.json | 110 ++++++++ .../taiga_userstory_changed_reassigned.json | 95 +++++++ .../taiga_userstory_changed_reopened.json | 103 ++++++++ .../taiga/taiga_userstory_changed_status.json | 94 +++++++ .../taiga_userstory_changed_subject.json | 92 +++++++ .../taiga_userstory_changed_unblocked.json | 100 +++++++ .../taiga/taiga_userstory_created.json | 62 +++++ .../taiga/taiga_userstory_deleted.json | 46 ++++ zerver/tests/test_hooks.py | 217 +++++++++++++++ zerver/views/webhooks/taiga.py | 248 ++++++++++++++++++ zproject/urls.py | 1 + 48 files changed, 3482 insertions(+), 1 deletion(-) create mode 100644 static/images/integrations/logos/taiga.png create mode 100644 static/images/integrations/taiga/001.png create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_assigned.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_comment_added.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_description.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_priority.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_reassigned.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_severity.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_status.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_subject.json create mode 100644 zerver/fixtures/taiga/taiga_issue_changed_type.json create mode 100644 zerver/fixtures/taiga/taiga_issue_created.json create mode 100644 zerver/fixtures/taiga/taiga_issue_deleted.json create mode 100644 zerver/fixtures/taiga/taiga_milestone_changed_name.json create mode 100644 zerver/fixtures/taiga/taiga_milestone_changed_time.json create mode 100644 zerver/fixtures/taiga/taiga_milestone_created.json create mode 100644 zerver/fixtures/taiga/taiga_milestone_deleted.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_assigned.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_blocked.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_comment_added.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_description.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_reassigned.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_status.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_subject.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_unblocked.json create mode 100644 zerver/fixtures/taiga/taiga_task_changed_us.json create mode 100644 zerver/fixtures/taiga/taiga_task_created.json create mode 100644 zerver/fixtures/taiga/taiga_task_deleted.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_assigned.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_blocked.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_closed.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_comment_added.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_description.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_milestone.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_new_milestone.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_points.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_reassigned.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_reopened.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_status.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_subject.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_changed_unblocked.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_created.json create mode 100644 zerver/fixtures/taiga/taiga_userstory_deleted.json create mode 100644 zerver/views/webhooks/taiga.py diff --git a/changelog.md b/changelog.md index ec680c2947..c02a49f31c 100644 --- a/changelog.md +++ b/changelog.md @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. - Added documentation on using Hubot to integrate with useful services not yet integrated with Zulip directly (e.g. Google Hangouts). - Added new management command to test sending email from Zulip. -- Added Codeship, Pingdom, Teamcity, and Yo integrations. +- Added Codeship, Pingdom, Taiga, Teamcity, and Yo integrations. - Refactored the Zulip puppet modules to be more modular. - Refactored the Tornado event system, fixing old memory leaks. - Implemented running queue processors multithreaded in development, diff --git a/static/images/integrations/logos/taiga.png b/static/images/integrations/logos/taiga.png new file mode 100644 index 0000000000000000000000000000000000000000..a85b7838597b7f03c5f0c9b6efea2fd5bb357607 GIT binary patch literal 9074 zcmd5?g1iH#$d5AU4+!1ABczg`l*)2% zgHz8%Fg3Lb4|UHRdzYiruWz)s-SBO-_v*0B`1m+_F*ImuYCc-z`^5j!;20ImiDAVH|%aow0)AxBR{Me_lP+Cw< z8OWt7!|Yq?0V)wyN4u}1Py*PPk_IKE_-+B6js8oAzu22ybQhSVb5u@@fbfsadRIjo z?^ek_AdY9hg7bdeWM{*>B?nDKwl%<*>@_vKUBqTLAH!qP2pFO_+YAjTm$eDEPog!p z_eSV0c-~I}8xFaKd5tZoUB*+55gh$Hu)&MJS{MpNQK7U9HFuC$40vNU zL%BeqlYN2r9P%&nass|cYN_$%W0*kQ&sazNkTNPtplYHt$(odu6|0^xAU-`k9?i4T zc+$?mld{gl9LhDV21U2se2L8s*sqOkPYv|G#2dRMKoji?T&nYdpYxM6EZ;rphUWg! zJhxrY#(pdfDCPw3APo-y$BBhR%vlF%ixH}>;cWu%Aq`uRt&4Uop=ho5MjkRxCU670 zK#03S#Cv3jVKYAnr(523;&j#UgdaHTdA`Mbhkt3(86?%jau<5(=ocl=UHhovqAeB! zH4Sh6&p(TffMbym#F%*bg=q#5mI8!rUIGnu18^w7PAa4h*v2|T&lDpug|QCgKEKxP zGA5~y;Hcgj=A9w|qwh^1=dLBmm;jBa?H-n=05u>%j5<-KY8p37afU{*x2=3pf53J( zLU|@wbMeN>tiL9(OQFk+TdJW`k!?4NxuX&Cos6?`#CPDp$ zB?R)FP2NWyJr!Ja6f~uiRPgo^p0Vn{<#f^_e7psK?hmRorJ5{oB%WC~LfpCWG+mQ| zyvkdxHXArPX@!^^)hSRDq|_A~Z2PgMeRj9-RZ1U`=pvll*min9{ojh{y_x$?!NdDs zI%C36bizZ{!9WN|BI-$7BVz_5;9RS8n0YEO34&OQ{N|hnneyP9lzvAXUCNOg1tF3? zY<|IB>UB^|PvHd#8DzD)i#}jGtOO=!hGu#VKbUfN-1duR2OVkk6b#BMNPm-_jJu>0 zK*8>@%iMw;raDH??=|eQWcHlE1k0iO#{9EQj&lOkV(m{7ALigS-IdcQ@LrtAld1Q} zh{MkLyCz8UAhVw8TB|e3mFFcId*X%k98r^Ir_F_KxucXmQq}{pY*o7r>e5D2=S}a{Gk>!MZHAk8$#o(q?>xIVM)f^nLWhU7@MV#i+P&}wmJw+ z^M0Y=k!-!Q0bVV%x9_t$VIB1MUlT+NyW36(Q-aeQaltZ~nSoqO z$lyj{t)=032Ec9X%7xrX8Yxc|8r_9l`(wBmi={u(`;IbXGoIIFJme`7*Gxxi=d2`! z`B?L+8&0ru2r<1~nNh)^(SL(Ys{A3L-(N;3AYtS94;?f_EEgVggb2Ce6lfk?Sw#(y zlS`FfOOb4#1reM9CF{XzR@8^No8$j12u4B@5JKY6?Y>n1J?J>?oV$Zzw=RZe{vwkdJ^$-9p&$`Ki z*LJom{@bKkRs6^4idzaKX2b18d2dK7(x<}H9w6w|q4rhxb znkMwp=O1Nt>usD|IijZ}_GPNc$?C0`+It_1-YL>USi|spW7mopioVw8?B4tDm&DOs zLIwVpK_K6W>s);OR|dI32w^i+P@ed2=r<{}ZY4=1meB)oOTMNC>$@`I>ZcDG)K~1R zKOzE6PrIK&I*^Vl|ejBN4tU$_T z^~uyL?G6n#c+u^?f$@UCUl1$5Y86uLI(Ywxp|4*k-E6f}iJlra?8IbV&RKorOrjlM< z<9CUcM<^h@xbfmnNvLvm*=AjUt6nc@#q;f`ZbEPAfTeZC7#tewn9#dI+}N2teGJ3# zW+xhlE7z%(*WnssGDPy9#(GtlIg3{=)|^JfMmrO_ivD!6jU#a|LyWD>twoXnvE9pN zCqPVbV*5Z(x2U3ptwia3Pyi1mYYQ1%%w|Uuh6+`F0XsFm1+#~IH_PhORz%`l6MFl! zvfp)EEY)GHi|tcxilfPWs^DYaI_f<)Em)o7;;&d<8sqs<{M}+Q4Rpba zPWmmg96+UCVA;|tUgq{VBGboPZm?XWzM0kakFVqX06V%hQ?PM5F7a^_>rt~Z`3 zm7GPPD})-`-;{)F5w<(#LY>h+3qxcm=S2;Ep2i>j5YYMET3yjuDFWKjP%OHINKTd9BL6+S?pV*ez) zXmxjMEW{zzZ~?SN0}#%DM_FR=j3x@N5hw2H7UE6C4gMdBn+T@%m*Ow6$wt3Bw^GwWVA!$N`~R#2;}k>=(-^&GAi3d{CQu(Q zwsEGcCYNYY3j}KSaGD+JJZBJ{F(&potyIg94ruJ-zg^yWk*qv)dFE==`ro+n;N{Xa zp_?VqYh_!3dXH3Wb}F7hsz2cDm*|09>UEl%RtGg4p@ZMfgrlR3*KqgE$1YLjdc;^I z`gn&FyBGyj=Vo{dq0zXS&)9W59Z%d#8{gUFAnhORjr--{2IaDEyH9EsE%~(6EvhkB zLgp_4N&~B~M$~^1;=~EVm3EM+L1xB!!X&FaJwGssqrcjyr0ZKqat*V{1FScxcITUR z=6Q;}ODxWy*-qj+TD+9S_AlZP2fUn>o1UJe@gS|d?01Jp(j}oSByM)srxHE8wFEH) zCrqWD`7(r1wW+Lm!ZKKK7%C_r^=YxAvH8_ow4D@~3_3r@t30FNBR2>|FQ63kB3`6jM@x<`>D+&(9(70 zDU$V9*7H^Yh!??)pLhEH%~E6R(=qqN9eO19%sY%Zx$+)u%-BdGpf@^nB zC?HjR&iw}!VNO_(jhcPq&k`mav?oThJ??p~eI=VJ~f6|KlZ(hv8V=yd!U-j*}R8 z`Z;X=*NL1Li&qyoQnW|kS{jv)#ocH#8~=xDLN1bgMYQej3o#F>Za=xyu286qgSdYb z)q&&=nG^p}iO5B(lCA5Y+)1|oC9(-10!+-cZ9IiJ7i&9 z#HP1bm$@D%NXgABl_KhG=?ufKwv~kISs%P%J_M&NGQfe%r}f9r>-tVSj`7j_U7Q7u z5*MCb=Y(ID$@(symPKi_OwMRbrKJvG<%<=gyr2=U;mh3DE43>eoi1WTJRv}HTTE>3 zp3f<=6#L}dHH&W?Avf9tvf*F& zRZPYu>_8&ygg|!e(ll<$Lj5UV+wEc+v&giS$aH3hK{iL2#SM-Zdoq+qbQiFcEnVLG z#8ewfn+5IS(*_`NWUXdY%c+Yr*d)PldxCaf(vM}ynWLc9m8;Mfkx<8*CEa=|8!7wo z$`iJ8t~zAdv3W2eSC8R`a6>-wAmqEE5AhSTkINnST?IuP`g&LX)69r0L@XYr;-evD zvvWi?u^Mbk9!*Y_)@oX@M$>=do@YNm5jdqO$2zwbHcta(*rgYFx;g6r>?1f?0<*x; zUaOtw(____);loFVlq=x?eNKB-pOoy>Ee@j8&cO;FD%Kz_vq%I9X{{Q^mz4-o)dO@ zt%=K-nKK^@^%G@qniyZJp^W>GI1$@w&&2R|?tRg*7lg6I*0J5h<(){3`wdf|?~n*d z$G=L>2X(41knZ};VhbEfiT!M2# zHZ_bOGFiv?;u*PYI@g7`19}4PY$gA6<}*gmOS6$-nh+!8$LA)Ba)@pxBC6Y{gB)WY}c=(y%TL;_A~YU-9_keUL8 zxb!n}{Dqe{hWB&WfT|O*V&E0PtAboyJ(~~K6l2oO&(iPH$8q7;KG2t786h(jZwsH5 zF^PIbj~ctNvzA*jB9-qel4ab0xmOxai%6Fof>tt3QlsMmgxx+Lk{z>0kuMHH$5pc2|E#C|#uccG5JrHwF)`*X{ z^xV>0hQ?!gu@VfdoNq5Y(*P8ncyhu{6jd;V{5Bd3!eC6Vkx5f!qCo95<8`TS=rEZ5D*vP-t9Nsq=h88NF9MD;%-UH6M)i~_)KpNPNBX>S`ip*D z1eO=q?x)~f{$w+oa*JDJyx<0Imwx3MU-EXNd#9$HVL?kaGb?l452*a?5}>gO*OC>r zIf!DIc4%>(|KwVY_nPLTYz>lN(JOr*R_gkywo1ODt}GHilsj)>D05p5Tkqyk@Fy3M zGuSuT*!RS@&B_rKF2pKN7bbJada?La^7;E&aZmn$^v-u*_sI7>Z$Bc%F)~ROIV^b; zXR8xxuQb(0h+;fn{vo*|Wh#P#4x|a&@$W4aJ>u=O1O~AM*AMqcTQw{#gMVyM5xbse ztW&jF)pVv{uohB9pHN})m!>xG;(!YMbVF~r{kr4tpr79?S?U;LJniFG*s`C$Z4UV; z_=*PcSewIamK(55M6C`7p#GRzs$(|E1x(NE*bb!JDT?h4ZIc#+wZ+fGfm1e#09W{5 z3eeAXh_~7=U=hl7ufAG~y>OV|?Dp_-FcD>hUuW0ZHBDP9D|WFAU28p!v$=Y)Aj7+$ zbp!^(W!JEt=i@JW>5^l2!8L+KV-_NOln9e~R_ZGmd87LEIMkf`hr!K_0Pk@A8uSo? zz17}iR+!@CY57ck+WP{~`Vlk6LX3zDRubhn>XvVW37W=?N8(HNeJ#OC>*vebn#|_u zpP$Z+=|;u>sw-_(Q6hel=({!SvfmU^sXfCDz)}rNK;>2EM+9`px@wc7B2NES*ek{4 zxW!Ic;P|m(BDeb%6Y-;oIC^dy!Kd}yjb2<65^pZikZX01P@Sy-VOMMjH|}LyG<-%2 zWtAy{)kkFN2n=dSre(#lYL8>~rVo7N;Cs76(N;*D+?IV(P0b=n7xZx`Y_fmIrVvK_ zXbMHgz4_^!y%kY=Je^c3O`ZzG zSM{RsyO4Uq3-FJZnh;s`(~Tblvh2SxA|>2{nf-y@9&LB8Akl3yfr2D-21mi4o+DYu zo^N`Bergp=#0P$^_n$bCQVK`MeC-1MQJs9qTq$!NHs}ehn@*Zq6{C!OFNq~{VWINR zAl?SF3VC!mU0^jYng6=5a5U7{bJ+`)-ugW}P8d`D&bbxfNGqCuEl#xa5Bd=}$()6b zJ^R4-X~5tGEb;@{ z9Bb3?g%zV$5!;6h3G_rZce&lR6W@0v71k;hLs1=MojT{4Bzmnp`_$Dfs$J^FoV_6j zxj=QUosopB*Ra9k;qIk;M7WuhdvS(6-SZZ~eB;{uql;aa7p_`e<-L+*eFAr@Dn_F# zqb3Z*rDCVQ!Z&}IMQsmAdgT;mq=stABEdCif3A6Vq%CeXrqtIGCNd~f>Iv6{-WJ>p z-Px@F#aX?w{H`Wr^opU|(3{|qPWGFfN#@Jg&xle97Sul*FF`iNyuKm||DxQf)B&;y z_>4 zWXTg_e>fK#kak`L-S!|Mtakjq+1tM3%jf!49lTS5Wq}bNAbef)yV-JySTTlM$8X3S?7)7$L$Jxji- z==6_$D(K@srD5o~rv(9tOf+-%za4W4E`rQz2Xpric%!Ays{8zSd_0mO=ZVG0h^5GG z@Nz|fYPbwIEmf#z*(aR-(WU@?ttLm}s< z!3!jDZQS@1`cwKq1Z({?xGGrrD`l>6PsN1fh?QG7dqxCm{4`gce;OX_8L6qUH#l;+ z4j$;uPc5zy{78!i=tH_c3`C+Co6)G!4zMH^4NNDZ^cpg{_1r&J)oj^w#4!K|8jT2- zTXUB7SKr`Tg{ueFuxpe2KyDP-uk0%ZwXeJN$_4CY?|YDhUL`nP-Kzg3Z}&LAg+^~a z2s$Ni)B@Vq$OkfGRabTeu~f|RO%-XkmlEQeI$wm~=tb`Jfh( zw;QT`Z>0`gYpYD`=VXa+IeBBL@A*EO4u>g{ygR*;)}eT*0kC!rF7r! zEv+6xily7y+uAZYT_TlM1XjL4Q3Eq(b{4dv;S1BN+S0Cw;h#2EQmA)%EcN5pYSPk( znFVQI+?et&GS|oM2Mre54ThiXe+V0?P8j;#r(;*OhEtB%n9ObT#3WAvLzA}!D+eNQ zXLW8>-U!PkMI@n#qROidZC_7XVjPp5lm67L zJBWXeFt~CS$(No2_%LBKDFxACP(wy^eqa}xMaWvRI9~cK9K)|FZ3q-uWkLec8}zR`qD=TH~~XB ze_3;Xq_DdAZKE5;duP*za`kuElag*_npNjp+A}TB?`DqlNnVX%v<$>+sIh3U;|%vXg$|(a$GT zQZ&OOydrmBkBi8I)F97TzOd2=54_bonI+^#&WdFY_I0=u^-x(1j+Zk$cR#uDhD{8f zbd=nbRXu7tHx(BU-rOH_8*cq9!r49ybyR)X_x-qWO(#wc zM7q8m2<$bNjR7ex&HzCE_xvn?9%%O3CGou9vwOg?QcM;hUD~e>og+~8lU9N~s?qlF zHyEF+oMTa{7mI}1hOGBsv!A)Vwf@c9`-7hkSA~x6n?*k%)v+j6Hy@RCX0`A7f z*By*0MNd(t?v!69$7_QA8ZvONzA3cL?gH9~{J3}Nb+;`eb10o@&(c}TbF-!k)5R*; znPs%JxIiQ&K8rV3iguc;i-ZC@v_(6YE?+Vf0rX9w-ge;LanHo@@;LBWNp5%>{FF^I z&kv7@o&3|&+uuhX()Ys*dtrLdPDy2kOlW&|nhBVP%XyLC#VIZHQ!oaCJL6=aHdJzX z1gdD7`8l_fNxL{7fH^cvT2{3In8xrZ&E5h9q!dDwnsvba_*QU;E#S0);`t$ev3HuA+lHk+(St z1nUADbiip=Tnd)Fi{wd1i^IuNO(#)LVyLF+z)>StsWodMw74XY^1mzIEI^}f9Tvx* zkC6wzjxqlOt?y~3 literal 0 HcmV?d00001 diff --git a/static/images/integrations/taiga/001.png b/static/images/integrations/taiga/001.png new file mode 100644 index 0000000000000000000000000000000000000000..a9899367582b45e852f5c13d8bf5a66e35e9c7e8 GIT binary patch literal 15819 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 R$b;8VQeyI=)xw5>{|k-t>HYu! literal 0 HcmV?d00001 diff --git a/templates/zerver/integrations.html b/templates/zerver/integrations.html index 0991517186..2ec5f2177f 100644 --- a/templates/zerver/integrations.html +++ b/templates/zerver/integrations.html @@ -221,6 +221,12 @@ Subversion + +
+ +

Go on your Zulip settings page, create a Taiga bot. + Please note the bot name and API key.

+ +

Since Taiga allows you to integrate services on a per + project basis, you have to perform the following steps + for every project that you want to send + notifications to Zulip.

+ +
    +
  1. +

    Go to Admin > Integration > Webhooks menu.

    +
  2. +
  3. +

    Click Add a new webhook.

    +
  4. +
  5. +

    Fill out the form by following the instructions: +

      +
    • + Name - to recognize this service, preferably Zulip +
    • +
    • + URL - +
      +{{ external_api_uri }}/v1/external/taiga?stream=STREAM_NAME&topic=TOPIC_NAME&api_key=BOT_API_KEY
      +
        +
      • STREAM_NAME - The url-encoded name of + stream which you want to receive notifications. + You can use an existing Zulip stream or create a + new one for this. +
      • +
      • TOPIC_NAME - The url-encoded + topic where your Taiga notifications will be + posted. (Read the notes below.)
      • +
      • BOT_API_KEY - API key created in Zulip.
      • +
      +

      Remember to url-encode the stream and topic + names. E.g. spaces need to be replaced + with %20 (e.g. so if you want your stream + to be called "My awesome project", STREAM_NAME + should be My%20awesome%20project).

      +
    • +
    • + Secret key - once again the API key created in Zulip. +
    • +
    +

    +
  6. +
  7. +

    Click Save once you've finished filling out the form.

    +
  8. +
+

That's it! Your actions on Taiga should now cause + notifications on the Zulip stream you specified above. +


+ + There are two different ways you may want to consider + when organizing your Taiga - Zulip integration:

+
    +
  • + Use special Zulip stream for Taiga messages - name + it Taiga. (Make sure to create this stream + first!) For every integrated project, provide a new topic. +
    +STREAM_NAME = Taiga
    +TOPIC = Project
    +
  • +
  • + If you already have a Zulip stream for managing a project, + you can also use this existing stream and add Taiga + notifications using special topic.(Remember about + substituting spaces with %20).
    +STREAM_NAME = My%20existing%20Zulip%20stream
    +TOPIC = Taiga
    +
  • +
+ +
+

See your Teamcity build status in Zulip!

diff --git a/zerver/fixtures/taiga/taiga_issue_changed_assigned.json b/zerver/fixtures/taiga/taiga_issue_changed_assigned.json new file mode 100644 index 0000000000..28f697b8b5 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_assigned.json @@ -0,0 +1,70 @@ +{ + "type":"issue", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 126383 + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "id":270391, + "version":3, + "is_blocked":false, + "blocked_note":"", + "ref":13, + "status":864973, + "severity":616377, + "priority":371208, + "type":372884, + "milestone":null, + "project":123471, + "created_date":"2016-04-13T19:36:12+0000", + "modified_date":"2016-04-14T10:15:51+0000", + "finished_date":null, + "subject":"Aaaa", + "description":"", + "external_reference":null + }, + "change":{ + "diff":{ + "assigned_to":{ + "to":126383, + "from":null + } + }, + "snapshot":null, + "values":{ + "users":{ + "126383":"Antek" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"dd7a7a38-0229-11e6-a7fd-52540016253e", + "created_at":"2016-04-14T10:15:51+0000", + "type":1, + "key":"issues.issue:270391", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_comment_added.json b/zerver/fixtures/taiga/taiga_issue_changed_comment_added.json new file mode 100644 index 0000000000..dd34a01a2f --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_comment_added.json @@ -0,0 +1,62 @@ +{ + "change":{ + "diff":{ + + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"00f6dad6-01af-11e6-ba7b-52540016253e", + "created_at":"2016-04-13T19:36:22+0000", + "type":1, + "key":"issues.issue:270391", + "comment":"Hobbits are in Isengard.", + "comment_html":"

Hobbits are in Isengard.

", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"issue", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 126383 + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":270391, + "version":2, + "is_blocked":false, + "blocked_note":"", + "ref":13, + "status":864973, + "severity":616377, + "priority":371208, + "type":372884, + "milestone":null, + "project":123471, + "created_date":"2016-04-13T19:36:12+0000", + "modified_date":"2016-04-13T19:36:22+0000", + "finished_date":null, + "subject":"Aaaa", + "description":"", + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_description.json b/zerver/fixtures/taiga/taiga_issue_changed_description.json new file mode 100644 index 0000000000..91c997b6d3 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_description.json @@ -0,0 +1,72 @@ +{ + "type":"issue", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 126383 + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":128024, + "name":"Han Solo" + }, + "id":270391, + "version":6, + "is_blocked":false, + "blocked_note":"", + "ref":13, + "status":864973, + "severity":616377, + "priority":371208, + "type":372884, + "milestone":null, + "project":123471, + "created_date":"2016-04-13T19:36:12+0000", + "modified_date":"2016-04-14T10:18:26+0000", + "finished_date":null, + "subject":"More descriptive name", + "description":"More descriptive description\n", + "external_reference":null + }, + "change":{ + "diff":{ + "description":{ + "to":"More descriptive description\n", + "from":"" + }, + "description_html":{ + "to":"

More descriptive description

", + "from":"" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"3a32ed5a-022a-11e6-9bc0-52540016141a", + "created_at":"2016-04-14T10:18:26+0000", + "type":1, + "key":"issues.issue:270391", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_priority.json b/zerver/fixtures/taiga/taiga_issue_changed_priority.json new file mode 100644 index 0000000000..985b5b5711 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_priority.json @@ -0,0 +1,68 @@ +{ + "change":{ + "diff":{ + "priority":{ + "from":367852, + "to":367853 + } + }, + "snapshot":null, + "values":{ + "priority":{ + "367853":"High", + "367852":"Normal" + } + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"1ab7d0c4-fcd7-11e5-a7a3-52540016141a", + "created_at":"2016-04-07T15:40:50+0000", + "type":1, + "key":"issues.issue:264165", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":264165, + "version":4, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "status":857143, + "severity":610790, + "priority":367853, + "type":369483, + "milestone":null, + "project":122355, + "created_date":"2016-04-07T15:37:41+0000", + "modified_date":"2016-04-07T15:40:49+0000", + "finished_date":null, + "subject":"A new issue", + "description":"", + "external_reference":null + }, + "type":"issue", + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_reassigned.json b/zerver/fixtures/taiga/taiga_issue_changed_reassigned.json new file mode 100644 index 0000000000..44c58ab50d --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_reassigned.json @@ -0,0 +1,71 @@ +{ + "change":{ + "diff":{ + "assigned_to":{ + "to":128024, + "from":126383 + } + }, + "snapshot":null, + "values":{ + "users":{ + "128024":"Han Solo", + "126383":"Antek" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"df555558-0229-11e6-b5ec-52540016253e", + "created_at":"2016-04-14T10:15:54+0000", + "type":1, + "key":"issues.issue:270391", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"issue", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 126383 + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":128024, + "name":"Han Solo" + }, + "id":270391, + "version":4, + "is_blocked":false, + "blocked_note":"", + "ref":13, + "status":864973, + "severity":616377, + "priority":371208, + "type":372884, + "milestone":null, + "project":123471, + "created_date":"2016-04-13T19:36:12+0000", + "modified_date":"2016-04-14T10:15:54+0000", + "finished_date":null, + "subject":"Aaaa", + "description":"", + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_severity.json b/zerver/fixtures/taiga/taiga_issue_changed_severity.json new file mode 100644 index 0000000000..7c89324da1 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_severity.json @@ -0,0 +1,68 @@ +{ + "change":{ + "diff":{ + "severity":{ + "from":610789, + "to":610790 + } + }, + "snapshot":null, + "values":{ + "severity":{ + "610789":"Important", + "610790":"Critical" + } + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"cd061cd2-fcd6-11e5-9191-52540016253e", + "created_at":"2016-04-07T15:38:39+0000", + "type":1, + "key":"issues.issue:264165", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":264165, + "version":2, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "status":857143, + "severity":610790, + "priority":367852, + "type":369481, + "milestone":null, + "project":122355, + "created_date":"2016-04-07T15:37:41+0000", + "modified_date":"2016-04-07T15:38:39+0000", + "finished_date":null, + "subject":"A new issue", + "description":"", + "external_reference":null + }, + "type":"issue", + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_status.json b/zerver/fixtures/taiga/taiga_issue_changed_status.json new file mode 100644 index 0000000000..4bdc2e28b4 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_status.json @@ -0,0 +1,68 @@ +{ + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":264165, + "version":5, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "status":857148, + "severity":610790, + "priority":367853, + "type":369483, + "milestone":null, + "project":122355, + "created_date":"2016-04-07T15:37:41+0000", + "modified_date":"2016-04-07T15:42:52+0000", + "finished_date":"2016-04-07T15:42:52+0000", + "subject":"A new issue", + "description":"", + "external_reference":null + }, + "action":"change", + "type":"issue", + "change":{ + "diff":{ + "status":{ + "to":857148, + "from":857143 + } + }, + "snapshot":null, + "values":{ + "status":{ + "857148":"Rejected", + "857143":"New" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"6392653e-fcd7-11e5-813a-52540016253e", + "created_at":"2016-04-07T15:42:52+0000", + "type":1, + "key":"issues.issue:264165", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + } +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_subject.json b/zerver/fixtures/taiga/taiga_issue_changed_subject.json new file mode 100644 index 0000000000..5a2ba9d275 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_subject.json @@ -0,0 +1,68 @@ +{ + "change":{ + "diff":{ + "subject":{ + "to":"More descriptive name", + "from":"Aaaa" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"33bb1cfe-022a-11e6-a7fd-52540016253e", + "created_at":"2016-04-14T10:18:16+0000", + "type":1, + "key":"issues.issue:270391", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"issue", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 126383 + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":128024, + "name":"Han Solo" + }, + "id":270391, + "version":5, + "is_blocked":false, + "blocked_note":"", + "ref":13, + "status":864973, + "severity":616377, + "priority":371208, + "type":372884, + "milestone":null, + "project":123471, + "created_date":"2016-04-13T19:36:12+0000", + "modified_date":"2016-04-14T10:18:15+0000", + "finished_date":null, + "subject":"More descriptive name", + "description":"", + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_issue_changed_type.json b/zerver/fixtures/taiga/taiga_issue_changed_type.json new file mode 100644 index 0000000000..46add5acde --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_changed_type.json @@ -0,0 +1,68 @@ +{ + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":264165, + "version":3, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "status":857143, + "severity":610790, + "priority":367852, + "type":369483, + "milestone":null, + "project":122355, + "created_date":"2016-04-07T15:37:41+0000", + "modified_date":"2016-04-07T15:39:51+0000", + "finished_date":null, + "subject":"A new issue", + "description":"", + "external_reference":null + }, + "action":"change", + "type":"issue", + "change":{ + "diff":{ + "type":{ + "to":369483, + "from":369481 + } + }, + "snapshot":null, + "values":{ + "type":{ + "369481":"Bug", + "369483":"Enhancement" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"f79b7ec4-fcd6-11e5-be32-52540016253e", + "created_at":"2016-04-07T15:39:51+0000", + "type":1, + "key":"issues.issue:264165", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + } +} diff --git a/zerver/fixtures/taiga/taiga_issue_created.json b/zerver/fixtures/taiga/taiga_issue_created.json new file mode 100644 index 0000000000..f4cf0494c1 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_created.json @@ -0,0 +1,39 @@ +{ + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":264165, + "version":1, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "status":857143, + "severity":610789, + "priority":367852, + "type":369481, + "milestone":null, + "project":122355, + "created_date":"2016-04-07T15:37:41+0000", + "modified_date":"2016-04-07T15:37:41+0000", + "finished_date":null, + "subject":"A new issue", + "description":"", + "external_reference":null + }, + "type":"issue", + "action":"create" +} diff --git a/zerver/fixtures/taiga/taiga_issue_deleted.json b/zerver/fixtures/taiga/taiga_issue_deleted.json new file mode 100644 index 0000000000..e2cc3bb195 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_issue_deleted.json @@ -0,0 +1,38 @@ +{ + "deleted_date":"2016-04-13T19:03:29.859Z", + "type":"issue", + "data":{ + "custom_attributes_values":null, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":270368, + "version":1, + "is_blocked":false, + "blocked_note":"", + "ref":12, + "status":864973, + "severity":616377, + "priority":371208, + "type":372884, + "milestone":null, + "project":123471, + "created_date":"2016-04-13T19:03:20+0000", + "modified_date":"2016-04-13T19:03:20+0000", + "finished_date":null, + "subject":"Aaaa", + "description":"", + "external_reference":null + }, + "action":"delete" +} diff --git a/zerver/fixtures/taiga/taiga_milestone_changed_name.json b/zerver/fixtures/taiga/taiga_milestone_changed_name.json new file mode 100644 index 0000000000..77140bee55 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_milestone_changed_name.json @@ -0,0 +1,54 @@ +{ + "action":"change", + "change":{ + "diff":{ + "estimated_start":{ + "from":"2016-04-15", + "to":"2016-04-15" + }, + "estimated_finish":{ + "from":"2016-04-30", + "to":"2016-04-30" + }, + "name":{ + "from":"New sprint", + "to":"Newer sprint" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"a812e8e0-017e-11e6-a40d-52540016253e", + "created_at":"2016-04-13T13:50:17+0000", + "type":1, + "key":"milestones.milestone:70864", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"milestone", + "data":{ + "owner":{ + "id":126383, + "name":"Antek" + }, + "id":70864, + "name":"Newer sprint", + "slug":"new-sprint-71", + "project":123471, + "estimated_start":"2016-04-15", + "estimated_finish":"2016-04-30", + "created_date":"2016-04-13T11:50:24+0000", + "modified_date":"2016-04-13T13:50:17+0000", + "closed":false, + "disponibility":0.0 + } +} diff --git a/zerver/fixtures/taiga/taiga_milestone_changed_time.json b/zerver/fixtures/taiga/taiga_milestone_changed_time.json new file mode 100644 index 0000000000..b3d90f11c3 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_milestone_changed_time.json @@ -0,0 +1,50 @@ +{ + "type":"milestone", + "action":"change", + "change":{ + "diff":{ + "estimated_finish":{ + "from":"2016-04-27", + "to":"2016-04-30" + }, + "estimated_start":{ + "from":"2016-04-15", + "to":"2016-04-15" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"1e78d370-0173-11e6-8bc7-52540016253e", + "created_at":"2016-04-13T12:27:42+0000", + "type":1, + "key":"milestones.milestone:70864", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "owner":{ + "id":126383, + "name":"Antek" + }, + "id":70864, + "name":"New sprint", + "slug":"new-sprint-71", + "project":123471, + "estimated_start":"2016-04-15", + "estimated_finish":"2016-04-30", + "created_date":"2016-04-13T11:50:24+0000", + "modified_date":"2016-04-13T12:27:42+0000", + "closed":false, + "disponibility":0.0 + } +} diff --git a/zerver/fixtures/taiga/taiga_milestone_created.json b/zerver/fixtures/taiga/taiga_milestone_created.json new file mode 100644 index 0000000000..00649a38ee --- /dev/null +++ b/zerver/fixtures/taiga/taiga_milestone_created.json @@ -0,0 +1,20 @@ +{ + "type":"milestone", + "action":"create", + "data":{ + "owner":{ + "id":126383, + "name":"Antek" + }, + "id":70864, + "name":"New sprint", + "slug":"new-sprint-71", + "project":123471, + "estimated_start":"2016-04-13", + "estimated_finish":"2016-04-27", + "created_date":"2016-04-13T11:50:24+0000", + "modified_date":"2016-04-13T11:50:24+0000", + "closed":false, + "disponibility":0.0 + } +} diff --git a/zerver/fixtures/taiga/taiga_milestone_deleted.json b/zerver/fixtures/taiga/taiga_milestone_deleted.json new file mode 100644 index 0000000000..b7dc119d2c --- /dev/null +++ b/zerver/fixtures/taiga/taiga_milestone_deleted.json @@ -0,0 +1,21 @@ +{ + "action":"delete", + "deleted_date":"2016-04-13T13:54:36.446Z", + "type":"milestone", + "data":{ + "owner":{ + "id":126383, + "name":"Antek" + }, + "id":70864, + "name":"Newer sprint", + "slug":"new-sprint-71", + "project":123471, + "estimated_start":"2016-04-15", + "estimated_finish":"2016-04-30", + "created_date":"2016-04-13T11:50:24+0000", + "modified_date":"2016-04-13T13:50:17+0000", + "closed":false, + "disponibility":0.0 + } +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_assigned.json b/zerver/fixtures/taiga/taiga_task_changed_assigned.json new file mode 100644 index 0000000000..fb3811f8f5 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_assigned.json @@ -0,0 +1,71 @@ +{ + "change":{ + "diff":{ + "assigned_to":{ + "from":null, + "to":126383 + } + }, + "snapshot":null, + "values":{ + "users":{ + "126383":"Antek" + } + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"86df24e4-fcd4-11e5-b9e7-52540016253e", + "created_at":"2016-04-07T15:22:23+0000", + "type":1, + "key":"tasks.task:570983", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "id":570983, + "version":2, + "is_blocked":false, + "blocked_note":"", + "user_story":659643, + "ref":2, + "status":613055, + "project":122355, + "milestone":null, + "created_date":"2016-04-07T15:21:00+0000", + "modified_date":"2016-04-07T15:22:22+0000", + "finished_date":null, + "subject":"Aaaa", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + }, + "type":"task", + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_blocked.json b/zerver/fixtures/taiga/taiga_task_changed_blocked.json new file mode 100644 index 0000000000..7b5e70f9b7 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_blocked.json @@ -0,0 +1,74 @@ +{ + "type":"task", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":586596, + "version":2, + "is_blocked":true, + "blocked_note":"asdasdas", + "user_story":673841, + "ref":14, + "status":618680, + "project":123471, + "milestone":null, + "created_date":"2016-04-14T09:58:24+0000", + "modified_date":"2016-04-14T09:58:30+0000", + "finished_date":null, + "subject":"A new task", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + }, + "change":{ + "diff":{ + "blocked_note":{ + "to":"asdasdas", + "from":"" + }, + "is_blocked":{ + "to":true, + "from":false + }, + "blocked_note_html":{ + "to":"

asdasdas

", + "from":"" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"710a127a-0227-11e6-a735-52540016141a", + "created_at":"2016-04-14T09:58:30+0000", + "type":1, + "key":"tasks.task:586596", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_comment_added.json b/zerver/fixtures/taiga/taiga_task_changed_comment_added.json new file mode 100644 index 0000000000..b971ba3f4f --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_comment_added.json @@ -0,0 +1,66 @@ +{ + "type":"task", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 126383 + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "id":584538, + "version":5, + "is_blocked":false, + "blocked_note":"", + "user_story":672975, + "ref":5, + "status":618680, + "project":123471, + "milestone":70898, + "created_date":"2016-04-13T14:11:33+0000", + "modified_date":"2016-04-13T14:24:51+0000", + "finished_date":null, + "subject":"New task assigned and in progress", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + }, + "change":{ + "diff":{ + + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"7c42dcac-0183-11e6-8e0d-52540016253e", + "created_at":"2016-04-13T14:24:51+0000", + "type":1, + "key":"tasks.task:584538", + "comment":"New comment to the task!", + "comment_html":"

New comment to the task!

", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_description.json b/zerver/fixtures/taiga/taiga_task_changed_description.json new file mode 100644 index 0000000000..fa282767b7 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_description.json @@ -0,0 +1,70 @@ +{ + "change":{ + "diff":{ + "description_html":{ + "to":"

New, better description.

", + "from":"" + }, + "description":{ + "to":"New, better description.", + "from":"" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"6ab05b26-0229-11e6-a735-52540016141a", + "created_at":"2016-04-14T10:12:38+0000", + "type":1, + "key":"tasks.task:586596", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"task", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":586596, + "version":5, + "is_blocked":false, + "blocked_note":"", + "user_story":673841, + "ref":14, + "status":618680, + "project":123471, + "milestone":null, + "created_date":"2016-04-14T09:58:24+0000", + "modified_date":"2016-04-14T10:12:38+0000", + "finished_date":null, + "subject":"Even newer task.", + "us_order":1, + "taskboard_order":1, + "description":"New, better description.", + "is_iocaine":false, + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_reassigned.json b/zerver/fixtures/taiga/taiga_task_changed_reassigned.json new file mode 100644 index 0000000000..362c663a3e --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_reassigned.json @@ -0,0 +1,72 @@ +{ + "change":{ + "diff":{ + "assigned_to":{ + "from":126384, + "to":126383 + } + }, + "snapshot":null, + "values":{ + "users":{ + "126383":"Antek", + "126384":"Han Solo" + } + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"86df24e4-fcd4-11e5-b9e7-52540016253e", + "created_at":"2016-04-07T15:22:23+0000", + "type":1, + "key":"tasks.task:570983", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "id":570983, + "version":2, + "is_blocked":false, + "blocked_note":"", + "user_story":659643, + "ref":2, + "status":613055, + "project":122355, + "milestone":null, + "created_date":"2016-04-07T15:21:00+0000", + "modified_date":"2016-04-07T15:22:22+0000", + "finished_date":null, + "subject":"Aaaa", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + }, + "type":"task", + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_status.json b/zerver/fixtures/taiga/taiga_task_changed_status.json new file mode 100644 index 0000000000..5a4ee174e1 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_status.json @@ -0,0 +1,72 @@ +{ + "change":{ + "diff":{ + "status":{ + "to":618680, + "from":618682 + } + }, + "snapshot":null, + "values":{ + "status":{ + "618682":"Ready for test", + "618680":"New" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"cb44c4e2-0182-11e6-8e0d-52540016253e", + "created_at":"2016-04-13T14:19:54+0000", + "type":1, + "key":"tasks.task:584538", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"task", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "id":584538, + "version":3, + "is_blocked":false, + "blocked_note":"", + "user_story":672975, + "ref":5, + "status":618680, + "project":123471, + "milestone":70898, + "created_date":"2016-04-13T14:11:33+0000", + "modified_date":"2016-04-13T14:19:54+0000", + "finished_date":null, + "subject":"New task assigned and in progress", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_subject.json b/zerver/fixtures/taiga/taiga_task_changed_subject.json new file mode 100644 index 0000000000..0d4cdc8d6e --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_subject.json @@ -0,0 +1,66 @@ +{ + "change":{ + "diff":{ + "subject":{ + "to":"Even newer task", + "from":"New task" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"13cbec1c-0229-11e6-955a-52540016253e", + "created_at":"2016-04-14T10:10:13+0000", + "type":1, + "key":"tasks.task:586596", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"task", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":586596, + "version":4, + "is_blocked":false, + "blocked_note":"", + "user_story":673841, + "ref":14, + "status":618680, + "project":123471, + "milestone":null, + "created_date":"2016-04-14T09:58:24+0000", + "modified_date":"2016-04-14T10:10:12+0000", + "finished_date":null, + "subject":"Even newer task.", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_unblocked.json b/zerver/fixtures/taiga/taiga_task_changed_unblocked.json new file mode 100644 index 0000000000..d8dbd3b5d9 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_unblocked.json @@ -0,0 +1,74 @@ +{ + "change":{ + "diff":{ + "blocked_note_html":{ + "to":"", + "from":"

asdasdas

" + }, + "blocked_note":{ + "to":"", + "from":"asdasdas" + }, + "is_blocked":{ + "to":false, + "from":true + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"90eb784a-0227-11e6-955a-52540016253e", + "created_at":"2016-04-14T09:59:23+0000", + "type":1, + "key":"tasks.task:586596", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"task", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":586596, + "version":3, + "is_blocked":false, + "blocked_note":"", + "user_story":673841, + "ref":14, + "status":618680, + "project":123471, + "milestone":null, + "created_date":"2016-04-14T09:58:24+0000", + "modified_date":"2016-04-14T09:59:23+0000", + "finished_date":null, + "subject":"A new task", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_task_changed_us.json b/zerver/fixtures/taiga/taiga_task_changed_us.json new file mode 100644 index 0000000000..55599658d5 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_changed_us.json @@ -0,0 +1,73 @@ +{ + "change":{ + "diff":{ + "user_story":{ + "to":673326, + "from":672975 + }, + "taskboard_order":{ + "to":0, + "from":1 + } + }, + "snapshot":null, + "values":{ + "user_story":{ + "673326":"#6 Greater US", + "672975":"#3 Great US" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"6ea553fa-0182-11e6-9f02-52540016141a", + "created_at":"2016-04-13T14:17:19+0000", + "type":1, + "key":"tasks.task:584537", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"task", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":584537, + "version":2, + "is_blocked":false, + "blocked_note":"", + "user_story":673326, + "ref":4, + "status":618680, + "project":123471, + "milestone":70898, + "created_date":"2016-04-13T14:11:15+0000", + "modified_date":"2016-04-13T14:17:19+0000", + "finished_date":null, + "subject":"A new task", + "us_order":1, + "taskboard_order":0, + "description":"", + "is_iocaine":false, + "external_reference":null + } +} diff --git a/zerver/fixtures/taiga/taiga_task_created.json b/zerver/fixtures/taiga/taiga_task_created.json new file mode 100644 index 0000000000..4a01971727 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_created.json @@ -0,0 +1,43 @@ +{ + "type":"task", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "id":584538, + "version":1, + "is_blocked":false, + "blocked_note":"", + "user_story":672975, + "ref":5, + "status":618681, + "project":123471, + "milestone":null, + "created_date":"2016-04-13T14:11:33+0000", + "modified_date":"2016-04-13T14:11:33+0000", + "finished_date":null, + "subject":"New task assigned and in progress", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + }, + "action":"create" +} diff --git a/zerver/fixtures/taiga/taiga_task_deleted.json b/zerver/fixtures/taiga/taiga_task_deleted.json new file mode 100644 index 0000000000..baf3b6cf28 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_task_deleted.json @@ -0,0 +1,39 @@ +{ + "deleted_date":"2016-04-13T18:10:06.594Z", + "type":"task", + "data":{ + "custom_attributes_values":null, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "id":585230, + "version":1, + "is_blocked":false, + "blocked_note":"", + "user_story":673841, + "ref":11, + "status":618680, + "project":123471, + "milestone":null, + "created_date":"2016-04-13T18:10:00+0000", + "modified_date":"2016-04-13T18:10:00+0000", + "finished_date":null, + "subject":"hhh", + "us_order":1, + "taskboard_order":1, + "description":"", + "is_iocaine":false, + "external_reference":null + }, + "action":"delete" +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_assigned.json b/zerver/fixtures/taiga/taiga_userstory_changed_assigned.json new file mode 100644 index 0000000000..abbd7c730f --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_assigned.json @@ -0,0 +1,94 @@ +{ + "change":{ + "diff":{ + "assigned_to":{ + "to":126383, + "from":null + } + }, + "snapshot":null, + "values":{ + "users":{ + "126383":"Antek" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"7c33d752-018d-11e6-b12d-52540016141a", + "created_at":"2016-04-13T15:36:26+0000", + "type":1, + "key":"userstories.userstory:672975", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"userstory", + "action":"change", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + } + ], + "id":672975, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "milestone":70898, + "project":123471, + "status":721850, + "is_closed":false, + "created_date":"2016-04-13T11:57:38+0000", + "modified_date":"2016-04-13T15:36:26+0000", + "finish_date":null, + "subject":"Great US", + "description":"", + "client_requirement":false, + "team_requirement":false, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_blocked.json b/zerver/fixtures/taiga/taiga_userstory_changed_blocked.json new file mode 100644 index 0000000000..68fa5186b3 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_blocked.json @@ -0,0 +1,100 @@ +{ + "type":"userstory", + "action":"change", + "change":{ + "diff":{ + "is_blocked":{ + "from":false, + "to":true + }, + "blocked_note":{ + "from":"", + "to":"Unsure what to do." + }, + "blocked_note_html":{ + "from":"", + "to":"

Unsure what to do.

" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"85838e40-016c-11e6-a653-52540016253e", + "created_at":"2016-04-13T11:40:28+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":true, + "blocked_note":"Unsure what to do.", + "ref":2, + "milestone":null, + "project":123471, + "status":721854, + "is_closed":true, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:40:28+0000", + "finish_date":"2016-04-13T11:38:06+0000", + "subject":"A newer hope", + "description":"", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_closed.json b/zerver/fixtures/taiga/taiga_userstory_changed_closed.json new file mode 100644 index 0000000000..8d9689f2cd --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_closed.json @@ -0,0 +1,103 @@ +{ + "type":"userstory", + "action":"change", + "change":{ + "diff":{ + "is_closed":{ + "from":false, + "to":true + }, + "status":{ + "from":721850, + "to":721854 + }, + "finish_date":{ + "from":"None", + "to":"2016-04-13 11:38:06.961674+00:00" + } + }, + "snapshot":null, + "values":{ + "status":{ + "721854":"Done", + "721850":"New" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"311b8ba0-016c-11e6-b505-52540016141a", + "created_at":"2016-04-13T11:38:07+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":false, + "blocked_note":"", + "ref":2, + "milestone":null, + "project":123471, + "status":721854, + "is_closed":true, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:38:06+0000", + "finish_date":"2016-04-13T11:38:06+0000", + "subject":"A newer hope", + "description":"", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_comment_added.json b/zerver/fixtures/taiga/taiga_userstory_changed_comment_added.json new file mode 100644 index 0000000000..31337b8ad3 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_comment_added.json @@ -0,0 +1,86 @@ +{ + "type":"userstory", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + } + ], + "id":672975, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "milestone":null, + "project":123471, + "status":721850, + "is_closed":false, + "created_date":"2016-04-13T11:57:38+0000", + "modified_date":"2016-04-13T14:04:55+0000", + "finish_date":null, + "subject":"Great US", + "description":"", + "client_requirement":false, + "team_requirement":false, + "generated_from_issue":null, + "tribe_gig":null + }, + "change":{ + "diff":{ + + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":128024, + "name":"Han Solo" + }, + "delete_comment_user":null, + "id":"b37f12ce-0180-11e6-97aa-52540016253e", + "created_at":"2016-04-13T14:04:56+0000", + "type":1, + "key":"userstories.userstory:672975", + "comment":"Hello!", + "comment_html":"

Hello!

", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_description.json b/zerver/fixtures/taiga/taiga_userstory_changed_description.json new file mode 100644 index 0000000000..aa944ff1b1 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_description.json @@ -0,0 +1,96 @@ +{ + "type":"userstory", + "action":"change", + "change":{ + "diff":{ + "description_html":{ + "from":"", + "to":"

new description hello

" + }, + "description":{ + "from":"", + "to":"new description hello\n" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"0ba5fada-016d-11e6-a653-52540016253e", + "created_at":"2016-04-13T11:44:13+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":true, + "blocked_note":"Baaaaaad US.", + "ref":2, + "milestone":null, + "project":123471, + "status":721854, + "is_closed":true, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:44:13+0000", + "finish_date":"2016-04-13T11:38:06+0000", + "subject":"A newer hope", + "description":"new description hello\n", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_milestone.json b/zerver/fixtures/taiga/taiga_userstory_changed_milestone.json new file mode 100644 index 0000000000..d0a2f98fc3 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_milestone.json @@ -0,0 +1,95 @@ +{ + "action":"change", + "change":{ + "diff":{ + "milestone":{ + "from":70865, + "to":70864 + } + }, + "snapshot":null, + "values":{ + "milestone":{ + "70865": "Old sprint", + "70864":"New sprint" + } + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"2aec6342-016e-11e6-9744-52540016141a", + "created_at":"2016-04-13T11:52:15+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"userstory", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":true, + "blocked_note":"Baaaaaad US.", + "ref":2, + "milestone":70864, + "project":123471, + "status":721854, + "is_closed":true, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:52:15+0000", + "finish_date":"2016-04-13T11:38:06+0000", + "subject":"A newer hope", + "description":"new description hello\n", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_new_milestone.json b/zerver/fixtures/taiga/taiga_userstory_changed_new_milestone.json new file mode 100644 index 0000000000..fa65f7db8d --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_new_milestone.json @@ -0,0 +1,94 @@ +{ + "action":"change", + "change":{ + "diff":{ + "milestone":{ + "from":null, + "to":70864 + } + }, + "snapshot":null, + "values":{ + "milestone":{ + "70864":"New sprint" + } + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"2aec6342-016e-11e6-9744-52540016141a", + "created_at":"2016-04-13T11:52:15+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"userstory", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":true, + "blocked_note":"Baaaaaad US.", + "ref":2, + "milestone":70864, + "project":123471, + "status":721854, + "is_closed":true, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:52:15+0000", + "finish_date":"2016-04-13T11:38:06+0000", + "subject":"A newer hope", + "description":"new description hello\n", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_points.json b/zerver/fixtures/taiga/taiga_userstory_changed_points.json new file mode 100644 index 0000000000..ec6c347862 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_points.json @@ -0,0 +1,110 @@ +{ + "type":"userstory", + "action":"change", + "change":{ + "diff":{ + "points":{ + "from":{ + "750724":1483752, + "750723":1483752, + "750726":1483752, + "750725":1483752 + }, + "to":{ + "750724":1483752, + "750723":1483757, + "750726":1483752, + "750725":1483752 + } + } + }, + "snapshot":null, + "values":{ + "points":{ + "1483757":"3", + "1483752":"?" + }, + "roles":{ + "750724":"Design", + "750723":"UX", + "750726":"Back", + "750725":"Front" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"3a7a4cc4-016a-11e6-a3b9-52540016253e", + "created_at":"2016-04-13T11:24:04+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":false, + "blocked_note":"", + "ref":2, + "milestone":null, + "project":123471, + "status":721850, + "is_closed":false, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:24:03+0000", + "finish_date":null, + "subject":"A new hope", + "description":"", + "client_requirement":false, + "team_requirement":false, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_reassigned.json b/zerver/fixtures/taiga/taiga_userstory_changed_reassigned.json new file mode 100644 index 0000000000..f3ec6a6e77 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_reassigned.json @@ -0,0 +1,95 @@ +{ + "type":"userstory", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":128024, + "name":"Han Solo" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + } + ], + "id":672975, + "is_blocked":false, + "blocked_note":"", + "ref":3, + "milestone":70898, + "project":123471, + "status":721850, + "is_closed":false, + "created_date":"2016-04-13T11:57:38+0000", + "modified_date":"2016-04-13T16:54:19+0000", + "finish_date":null, + "subject":"Great US", + "description":"", + "client_requirement":false, + "team_requirement":false, + "generated_from_issue":null, + "tribe_gig":null + }, + "change":{ + "diff":{ + "assigned_to":{ + "to":128024, + "from":126383 + } + }, + "snapshot":null, + "values":{ + "users":{ + "126383":"Antek", + "128024":"Han Solo" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"5d94df0c-0198-11e6-811a-52540016253e", + "created_at":"2016-04-13T16:54:19+0000", + "type":1, + "key":"userstories.userstory:672975", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "action":"change" +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_reopened.json b/zerver/fixtures/taiga/taiga_userstory_changed_reopened.json new file mode 100644 index 0000000000..e22f06315d --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_reopened.json @@ -0,0 +1,103 @@ +{ + "type":"userstory", + "action":"change", + "change":{ + "diff":{ + "is_closed":{ + "from":true, + "to":false + }, + "status":{ + "from":721854, + "to":721850 + }, + "finish_date":{ + "from":"2016-04-13 11:38:06.961674+00:00", + "to":"None" + } + }, + "snapshot":null, + "values":{ + "status":{ + "721854":"Done", + "721850":"New" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"311b8ba0-016c-11e6-b505-52540016141a", + "created_at":"2016-04-13T11:38:07+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":false, + "blocked_note":"", + "ref":2, + "milestone":null, + "project":123471, + "status":721854, + "is_closed":true, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:38:06+0000", + "finish_date":"2016-04-13T11:38:06+0000", + "subject":"A newer hope", + "description":"", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_status.json b/zerver/fixtures/taiga/taiga_userstory_changed_status.json new file mode 100644 index 0000000000..3ca9207014 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_status.json @@ -0,0 +1,94 @@ +{ + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1470231, + "name":"?", + "value":null + }, + { + "id":1470231, + "name":"?", + "value":null + }, + { + "id":1470231, + "name":"?", + "value":null + }, + { + "id":1470231, + "name":"?", + "value":null + } + ], + "id":659643, + "is_blocked":false, + "blocked_note":"", + "ref":1, + "milestone":null, + "project":122355, + "status":715044, + "is_closed":false, + "created_date":"2016-04-07T14:43:23+0000", + "modified_date":"2016-04-07T15:35:34+0000", + "finish_date":null, + "subject":"A new hope", + "description":"asdasdas", + "client_requirement":false, + "team_requirement":false, + "generated_from_issue":null, + "tribe_gig":null + }, + "action":"change", + "type":"userstory", + "change":{ + "diff":{ + "status":{ + "to":715044, + "from":715040 + } + }, + "snapshot":null, + "values":{ + "status":{ + "715044":"Done", + "715040":"New" + } + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"5eb37680-fcd6-11e5-b9e7-52540016253e", + "created_at":"2016-04-07T15:35:34+0000", + "type":1, + "key":"userstories.userstory:659643", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_subject.json b/zerver/fixtures/taiga/taiga_userstory_changed_subject.json new file mode 100644 index 0000000000..71785f9912 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_subject.json @@ -0,0 +1,92 @@ +{ + "action":"change", + "change":{ + "diff":{ + "subject":{ + "from":"A new hope", + "to":"A newer hope" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "name":"Antek", + "pk":126383 + }, + "delete_comment_user":null, + "id":"031ea1ce-016c-11e6-a653-52540016253e", + "created_at":"2016-04-13T11:36:50+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "type":"userstory", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":false, + "blocked_note":"", + "ref":2, + "milestone":null, + "project":123471, + "status":721850, + "is_closed":false, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:36:49+0000", + "finish_date":null, + "subject":"A newer hope", + "description":"", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_changed_unblocked.json b/zerver/fixtures/taiga/taiga_userstory_changed_unblocked.json new file mode 100644 index 0000000000..e878812f49 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_changed_unblocked.json @@ -0,0 +1,100 @@ +{ + "type":"userstory", + "action":"change", + "change":{ + "diff":{ + "is_blocked":{ + "from":true, + "to":false + }, + "blocked_note":{ + "from":"Unsure what to do.", + "to":"" + }, + "blocked_note_html":{ + "from":"

Unsure what to do.

", + "to":"" + } + }, + "snapshot":null, + "values":{ + + }, + "user":{ + "pk":126383, + "name":"Antek" + }, + "delete_comment_user":null, + "id":"cdf8edb4-016c-11e6-a9ae-52540016253e", + "created_at":"2016-04-13T11:42:30+0000", + "type":1, + "key":"userstories.userstory:672899", + "comment":"", + "comment_html":"", + "delete_comment_date":null, + "is_hidden":false, + "is_snapshot":false + }, + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + }, + { + "id":1483757, + "name":"3", + "value":3.0 + } + ], + "id":672899, + "is_blocked":false, + "blocked_note":"", + "ref":2, + "milestone":null, + "project":123471, + "status":721854, + "is_closed":true, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:42:30+0000", + "finish_date":"2016-04-13T11:38:06+0000", + "subject":"A newer hope", + "description":"", + "client_requirement":false, + "team_requirement":true, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_created.json b/zerver/fixtures/taiga/taiga_userstory_created.json new file mode 100644 index 0000000000..d1e2c2aa0c --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_created.json @@ -0,0 +1,62 @@ +{ + "action":"create", + "type":"userstory", + "data":{ + "custom_attributes_values":{ + + }, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + + ], + "tags":[ + + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":null, + "points":[ + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + }, + { + "id":1483752, + "name":"?", + "value":null + } + ], + "id":672899, + "is_blocked":false, + "blocked_note":"", + "ref":2, + "milestone":null, + "project":123471, + "status":721850, + "is_closed":false, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:22:00+0000", + "finish_date":null, + "subject":"A new hope", + "description":"", + "client_requirement":false, + "team_requirement":false, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/fixtures/taiga/taiga_userstory_deleted.json b/zerver/fixtures/taiga/taiga_userstory_deleted.json new file mode 100644 index 0000000000..9c2a9587b4 --- /dev/null +++ b/zerver/fixtures/taiga/taiga_userstory_deleted.json @@ -0,0 +1,46 @@ +{ + "type":"userstory", + "action":"delete", + "deleted_date":"2016-04-13T11:56:17.654Z", + "data":{ + "custom_attributes_values":null, + "is_watcher":false, + "total_watchers":0, + "watchers":[ + 128024, + 126383 + ], + "tags":[ + "great tag" + ], + "external_reference":null, + "owner":{ + "id":126383, + "name":"Antek" + }, + "assigned_to":{ + "id":126383, + "name":"Antek" + }, + "points":[ + + ], + "id":672899, + "is_blocked":false, + "blocked_note":"", + "ref":2, + "milestone":70864, + "project":123471, + "status":721851, + "is_closed":false, + "created_date":"2016-04-13T11:22:00+0000", + "modified_date":"2016-04-13T11:54:36+0000", + "finish_date":null, + "subject":"A newer hope", + "description":"new description hello\n", + "client_requirement":false, + "team_requirement":false, + "generated_from_issue":null, + "tribe_gig":null + } +} diff --git a/zerver/tests/test_hooks.py b/zerver/tests/test_hooks.py index fb0dba9da5..6b2086c4aa 100644 --- a/zerver/tests/test_hooks.py +++ b/zerver/tests/test_hooks.py @@ -1065,3 +1065,220 @@ class CodeshipHookTests(AuthedTestCase): result = self.client.post(self._url, json, stream_name=self.STREAM_NAME, content_type="application/json") self.assert_json_success(result) return result + +class TaigaHookTests(AuthedTestCase): + + def send_taiga_message(self, action): + email = "hamlet@zulip.com" + api_key = self.get_api_key(email) + stream = "taiga" + topic = "subject" + mesg = self.fixture_data("taiga", action, file_type="json") + url = "/api/v1/external/taiga?stream=%s&topic=%s&api_key=%s" % (stream, topic, api_key) + self.send_json_payload(email, url, mesg, stream_name=stream, content_type="application/json") + return self.get_last_message() + + def test_taiga_userstory_deleted(self): + msg = self.send_taiga_message("userstory_deleted") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':x: Antek deleted user story **A newer hope**.\n') + + def test_taiga_userstory_created(self): + msg = self.send_taiga_message("userstory_created") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':package: Antek created user story **A new hope**.\n') + + def test_taiga_userstory_changed_unblocked(self): + msg = self.send_taiga_message("userstory_changed_unblocked") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':unlock: Antek unblocked user story **A newer hope**.\n') + + def test_taiga_userstory_changed_subject(self): + msg = self.send_taiga_message("userstory_changed_subject") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':notebook: Antek renamed user story from A new hope to **A newer hope**.\n') + + def test_taiga_userstory_changed_status(self): + msg = self.send_taiga_message("userstory_changed_status") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':chart_with_upwards_trend: Antek changed status of user story **A new hope** from New to Done.\n') + + def test_taiga_userstory_changed_reassigned(self): + msg = self.send_taiga_message("userstory_changed_reassigned") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':busts_in_silhouette: Antek reassigned user story **Great US** from Antek to Han Solo.\n') + + def test_taiga_userstory_changed_points(self): + msg = self.send_taiga_message("userstory_changed_points") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':game_die: Antek changed estimation of user story **A new hope**.\n') + + def test_taiga_userstory_changed_new_milestone(self): + msg = self.send_taiga_message("userstory_changed_new_milestone") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':calendar: Antek added user story **A newer hope** to sprint New sprint.\n') + + def test_taiga_userstory_changed_milestone(self): + msg = self.send_taiga_message("userstory_changed_milestone") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':calendar: Antek changed sprint of user story **A newer hope** from Old sprint to New sprint.\n') + + def test_taiga_userstory_changed_description(self): + msg = self.send_taiga_message("userstory_changed_description") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':notebook: Antek updated description of user story **A newer hope**.\n') + + def test_taiga_userstory_changed_closed(self): + msg = self.send_taiga_message("userstory_changed_closed") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':chart_with_upwards_trend: Antek changed status of user story **A newer hope** from New to Done.\n:checkered_flag: Antek closed user story **A newer hope**.\n') + + def test_taiga_userstory_changed_reopened(self): + msg = self.send_taiga_message("userstory_changed_reopened") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':chart_with_upwards_trend: Antek changed status of user story **A newer hope** from Done to New.\n:package: Antek reopened user story **A newer hope**.\n') + + def test_taiga_userstory_changed_blocked(self): + msg = self.send_taiga_message("userstory_changed_blocked") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':lock: Antek blocked user story **A newer hope**.\n') + + def test_taiga_userstory_changed_assigned(self): + msg = self.send_taiga_message("userstory_changed_assigned") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':busts_in_silhouette: Antek assigned user story **Great US** to Antek.\n') + + def test_taiga_task_created(self): + msg = self.send_taiga_message("task_created") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':clipboard: Antek created task **New task assigned and in progress**.\n') + + def test_taiga_task_changed_status(self): + msg = self.send_taiga_message("task_changed_status") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':chart_with_upwards_trend: Antek changed status of task **New task assigned and in progress** from Ready for test to New.\n') + + def test_taiga_task_changed_blocked(self): + msg = self.send_taiga_message("task_changed_blocked") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':lock: Antek blocked task **A new task**.\n') + + def test_taiga_task_changed_unblocked(self): + msg = self.send_taiga_message("task_changed_unblocked") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':unlock: Antek unblocked task **A new task**.\n') + + def test_taiga_task_changed_assigned(self): + msg = self.send_taiga_message("task_changed_assigned") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':busts_in_silhouette: Antek assigned task **Aaaa** to Antek.\n') + + def test_taiga_task_changed_reassigned(self): + msg = self.send_taiga_message("task_changed_reassigned") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':busts_in_silhouette: Antek reassigned task **Aaaa** from Han Solo to Antek.\n') + + def test_taiga_task_changed_subject(self): + msg = self.send_taiga_message("task_changed_subject") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':notebook: Antek renamed task New task to **Even newer task**.\n') + + def test_taiga_task_changed_description(self): + msg = self.send_taiga_message("task_changed_description") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':notebook: Antek updated description of task **Even newer task.**.\n') + + def test_taiga_task_changed_us(self): + msg = self.send_taiga_message("task_changed_us") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':clipboard: Antek moved task **A new task** from user story #3 Great US to #6 Greater US.\n') + + def test_taiga_task_deleted(self): + msg = self.send_taiga_message("task_deleted") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':x: Antek deleted task **hhh**.\n') + + def test_taiga_milestone_created(self): + msg = self.send_taiga_message("milestone_created") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':calendar: Antek created sprint **New sprint**.\n') + + def test_taiga_milestone_deleted(self): + msg = self.send_taiga_message("milestone_deleted") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':x: Antek deleted sprint **Newer sprint**.\n') + + def test_taiga_milestone_changed_time(self): + msg = self.send_taiga_message("milestone_changed_time") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':calendar: Antek changed estimated finish of sprint **New sprint** from 2016-04-27 to 2016-04-30.\n') + + def test_taiga_milestone_changed_name(self): + msg = self.send_taiga_message("milestone_changed_name") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':notebook: Antek renamed sprint from New sprint to **Newer sprint**.\n') + + def test_taiga_issue_created(self): + msg = self.send_taiga_message("issue_created") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':bulb: Antek created issue **A new issue**.\n') + + def test_taiga_issue_deleted(self): + msg = self.send_taiga_message("issue_deleted") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':x: Antek deleted issue **Aaaa**.\n') + + def test_taiga_issue_changed_assigned(self): + msg = self.send_taiga_message("issue_changed_assigned") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':busts_in_silhouette: Antek assigned issue **Aaaa** to Antek.\n') + + def test_taiga_issue_changed_reassigned(self): + msg = self.send_taiga_message("issue_changed_reassigned") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':busts_in_silhouette: Antek reassigned issue **Aaaa** from Antek to Han Solo.\n') + + def test_taiga_issue_changed_subject(self): + msg = self.send_taiga_message("issue_changed_subject") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':notebook: Antek renamed issue Aaaa to **More descriptive name**.\n') + + def test_taiga_issue_changed_description(self): + msg = self.send_taiga_message("issue_changed_description") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':notebook: Antek updated description of issue **More descriptive name**.\n') + + def test_taiga_issue_changed_type(self): + msg = self.send_taiga_message("issue_changed_type") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':bulb: Antek changed type of issue **A new issue** from Bug to Enhancement.\n') + + def test_taiga_issue_changed_status(self): + msg = self.send_taiga_message("issue_changed_status") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':chart_with_upwards_trend: Antek changed status of issue **A new issue** from New to Rejected.\n') + + def test_taiga_issue_changed_severity(self): + msg = self.send_taiga_message("issue_changed_severity") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':warning: Antek changed severity of issue **A new issue** from Important to Critical.\n') + + def test_taiga_issue_changed_priority(self): + msg = self.send_taiga_message("issue_changed_priority") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':rocket: Antek changed priority of issue **A new issue** from Normal to High.\n') + + def test_taiga_userstory_comment_added(self): + msg = self.send_taiga_message("userstory_changed_comment_added") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':thought_balloon: Han Solo commented on user story **Great US**.\n') + + def test_taiga_task_changed_comment_added(self): + msg = self.send_taiga_message("task_changed_comment_added") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':thought_balloon: Antek commented on task **New task assigned and in progress**.\n') + + def test_taiga_issue_changed_comment_added(self): + msg = self.send_taiga_message("issue_changed_comment_added") + self.assertEqual(msg.subject, u'subject') + self.assertEqual(msg.content, u':thought_balloon: Antek commented on issue **Aaaa**.\n') diff --git a/zerver/views/webhooks/taiga.py b/zerver/views/webhooks/taiga.py new file mode 100644 index 0000000000..22be6e01c0 --- /dev/null +++ b/zerver/views/webhooks/taiga.py @@ -0,0 +1,248 @@ +""" +Taiga integration for Zulip. + +Tips for notification output: + +*Emojis*: most of the events have specific emojis e.g. +- :notebook: - change of subject/name/description +- :chart_with_upwards_trend: - change of status +etc. If no there's no meaningful emoji for certain event, the defaults are used: +- :thought_balloon: - event connected to commenting +- :busts_in_silhouette: - event connected to a certain user +- :package: - all other events connected to user story +- :calendar: - all other events connected to milestones +- :clipboard: - all other events connected to tasks +- :bulb: - all other events connected to issues + +*Text formatting*: if there has been a change of a property, the new value should always be in bold; otherwise the +subject of US/task should be in bold. +""" + +from __future__ import absolute_import +from zerver.models import get_client +from zerver.lib.actions import check_send_message +from zerver.lib.response import json_success, json_error +from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view + +import ujson +from six.moves import range + + +@api_key_only_webhook_view +@has_request_variables +def api_taiga_webhook(request, user_profile, stream=REQ(default='taiga'), topic=REQ(default='General')): + + try: + message = ujson.loads(request.body) + except ValueError: + return json_error("Malformed JSON input") + + parsed_events = parse_message(message) + + content = "" + for event in parsed_events: + content += generate_content(event) + '\n' + + check_send_message(user_profile, get_client('ZulipTaigaWebhook'), 'stream', [stream], topic, content) + + return json_success() + +templates = { + 'userstory': { + 'create': u':package: %(user)s created user story **%(subject)s**.', + 'set_assigned_to': u':busts_in_silhouette: %(user)s assigned user story **%(subject)s** to %(new)s.', + 'changed_assigned_to': u':busts_in_silhouette: %(user)s reassigned user story **%(subject)s** from %(old)s to %(new)s.', + 'points': u':game_die: %(user)s changed estimation of user story **%(subject)s**.', + 'blocked': u':lock: %(user)s blocked user story **%(subject)s**.', + 'unblocked': u':unlock: %(user)s unblocked user story **%(subject)s**.', + 'set_milestone': u':calendar: %(user)s added user story **%(subject)s** to sprint %(new)s.', + 'changed_milestone': u':calendar: %(user)s changed sprint of user story **%(subject)s** from %(old)s to %(new)s.', + 'changed_status': u':chart_with_upwards_trend: %(user)s changed status of user story **%(subject)s** from %(old)s to %(new)s.', + 'closed': u':checkered_flag: %(user)s closed user story **%(subject)s**.', + 'reopened': u':package: %(user)s reopened user story **%(subject)s**.', + 'renamed': u':notebook: %(user)s renamed user story from %(old)s to **%(new)s**.', + 'description': u':notebook: %(user)s updated description of user story **%(subject)s**.', + 'commented': u':thought_balloon: %(user)s commented on user story **%(subject)s**.', + 'delete': u':x: %(user)s deleted user story **%(subject)s**.' + }, + 'milestone': { + 'create': u':calendar: %(user)s created sprint **%(subject)s**.', + 'renamed': u':notebook: %(user)s renamed sprint from %(old)s to **%(new)s**.', + 'estimated_start': u':calendar: %(user)s changed estimated start of sprint **%(subject)s** from %(old)s to %(new)s.', + 'estimated_finish': u':calendar: %(user)s changed estimated finish of sprint **%(subject)s** from %(old)s to %(new)s.', + 'delete': u':x: %(user)s deleted sprint **%(subject)s**.' + }, + 'task': { + 'create': u':clipboard: %(user)s created task **%(subject)s**.', + 'set_assigned_to': u':busts_in_silhouette: %(user)s assigned task **%(subject)s** to %(new)s.', + 'changed_assigned_to': u':busts_in_silhouette: %(user)s reassigned task **%(subject)s** from %(old)s to %(new)s.', + 'blocked': u':lock: %(user)s blocked task **%(subject)s**.', + 'unblocked': u':unlock: %(user)s unblocked task **%(subject)s**.', + 'set_milestone': u':calendar: %(user)s added task **%(subject)s** to sprint %(new)s.', + 'changed_milestone': u':calendar: %(user)s changed sprint of task **%(subject)s** from %(old)s to %(new)s.', + 'changed_status': u':chart_with_upwards_trend: %(user)s changed status of task **%(subject)s** from %(old)s to %(new)s.', + 'renamed': u':notebook: %(user)s renamed task %(old)s to **%(new)s**.', + 'description': u':notebook: %(user)s updated description of task **%(subject)s**.', + 'commented': u':thought_balloon: %(user)s commented on task **%(subject)s**.', + 'delete': u':x: %(user)s deleted task **%(subject)s**.', + 'changed_us': u':clipboard: %(user)s moved task **%(subject)s** from user story %(old)s to %(new)s.' + }, + 'issue': { + 'create': u':bulb: %(user)s created issue **%(subject)s**.', + 'set_assigned_to': u':busts_in_silhouette: %(user)s assigned issue **%(subject)s** to %(new)s.', # + 'changed_assigned_to': u':busts_in_silhouette: %(user)s reassigned issue **%(subject)s** from %(old)s to %(new)s.', + 'changed_priority': u':rocket: %(user)s changed priority of issue **%(subject)s** from %(old)s to %(new)s.', + 'changed_severity': u':warning: %(user)s changed severity of issue **%(subject)s** from %(old)s to %(new)s.', + 'changed_status': u':chart_with_upwards_trend: %(user)s changed status of issue **%(subject)s** from %(old)s to %(new)s.', + 'changed_type': u':bulb: %(user)s changed type of issue **%(subject)s** from %(old)s to %(new)s.', + 'renamed': u':notebook: %(user)s renamed issue %(old)s to **%(new)s**.', + 'description': u':notebook: %(user)s updated description of issue **%(subject)s**.', + 'commented': u':thought_balloon: %(user)s commented on issue **%(subject)s**.', + 'delete': u':x: %(user)s deleted issue **%(subject)s**.' + }, +} + + +def get_old_and_new_values(change_type, message): + """ Parses the payload and finds previous and current value of change_type.""" + values_map = { + 'assigned_to': 'users', + 'status': 'status', + 'severity': 'severity', + 'priority': 'priority', + 'milestone': 'milestone', + 'type': 'type', + 'user_story': 'user_story' + } + + if change_type in ['subject', 'name', 'estimated_finish', 'estimated_start']: + old = message["change"]["diff"][change_type]["from"] + new = message["change"]["diff"][change_type]["to"] + return old, new + + try: + old_id = message["change"]["diff"][change_type]["from"] + old = message["change"]["values"][values_map[change_type]][str(old_id)] + except KeyError: + old = None + + try: + new_id = message["change"]["diff"][change_type]["to"] + new = message["change"]["values"][values_map[change_type]][str(new_id)] + except KeyError: + new = None + + return old, new + + +def parse_comment(message): + """ Parses the comment to issue, task or US. """ + return { + 'event': 'commented', + 'type': message["type"], + 'values': { + 'user': message["change"]["user"]["name"], + 'subject': message["data"]["subject"] if "subject" in list(message["data"].keys()) else message["data"]["name"] + } + } + +def parse_create_or_delete(message): + """ Parses create or delete event. """ + return { + 'type': message["type"], + 'event': message["action"], + 'values': + { + 'user': message["data"]["owner"]["name"], + 'subject': message["data"]["subject"] if "subject" in list(message["data"].keys()) else message["data"]["name"] + } + } + + +def parse_change_event(change_type, message): + """ Parses change event. """ + evt = {} + values = { + 'user': message["change"]["user"]["name"], + 'subject': message["data"]["subject"] if "subject" in list(message["data"].keys()) else message["data"]["name"] + } + + if change_type in ["description", "points"]: + event_type = change_type + + elif change_type in ["milestone", "assigned_to"]: + old, new = get_old_and_new_values(change_type, message) + if not old: + event_type = "set_" + change_type + values["new"] = new + else: + event_type = "changed_" + change_type + values.update({'old': old, 'new': new}) + + + elif change_type == "is_blocked": + if message["change"]["diff"]["is_blocked"]["to"]: + event_type = "blocked" + else: + event_type = "unblocked" + + elif change_type == "is_closed": + if message["change"]["diff"]["is_closed"]["to"]: + event_type = "closed" + else: + event_type = "reopened" + + elif change_type == "user_story": + old, new = get_old_and_new_values(change_type, message) + event_type = "changed_us" + values.update({'old': old, 'new': new}) + + elif change_type in ["subject", 'name']: + event_type = 'renamed' + old, new = get_old_and_new_values(change_type, message) + values.update({'old': old, 'new': new}) + + + elif change_type in ["estimated_finish", "estimated_start"]: + old, new = get_old_and_new_values(change_type, message) + if not old == new: + event_type = change_type + values.update({'old': old, 'new': new}) + else: + # date hasn't changed + return None + + elif change_type in ["priority", "severity", "type", "status"]: + event_type = 'changed_' + change_type + old, new = get_old_and_new_values(change_type, message) + values.update({'old': old, 'new': new}) + + else: + # we are not supporting this type of event + return None + + evt.update({"type": message["type"], "event": event_type, "values": values}) + return evt + + +def parse_message(message): + """ Parses the payload by delegating to specialized functions. """ + events = [] + if message["action"] in ['create', 'delete']: + events.append(parse_create_or_delete(message)) + elif message["action"] == 'change': + if message["change"]["diff"]: + for value in message["change"]["diff"]: + parsed_event = parse_change_event(value, message) + if parsed_event: events.append(parsed_event) + if message["change"]["comment"]: + events.append(parse_comment(message)) + + return events + +def generate_content(data): + """ Gets the template string and formats it with parsed data. """ + try: + return templates[data['type']][data['event']] % data['values'] + except KeyError: + return json_error("Unknown message") diff --git a/zproject/urls.py b/zproject/urls.py index e45bd09a63..670ad2f843 100644 --- a/zproject/urls.py +++ b/zproject/urls.py @@ -154,6 +154,7 @@ urlpatterns += patterns('zerver.views', url(r'^api/v1/external/pingdom$', 'webhooks.pingdom.api_pingdom_webhook'), url(r'^api/v1/external/pivotal$', 'webhooks.pivotal.api_pivotal_webhook'), url(r'^api/v1/external/stash$', 'webhooks.stash.api_stash_webhook'), + url(r'^api/v1/external/taiga$', 'webhooks.taiga.api_taiga_webhook'), url(r'^api/v1/external/teamcity$', 'webhooks.teamcity.api_teamcity_webhook'), url(r'^api/v1/external/travis$', 'webhooks.travis.api_travis_webhook'), url(r'^api/v1/external/yo$', 'webhooks.yo.api_yo_app_webhook'),