From 9f469d5f7b9bdc5850a9399e42463377fd9c64c5 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Tue, 26 May 2015 14:08:05 -0700 Subject: [PATCH 01/27] Bump version to 0.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9695288c..46c56405 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Kitematic", - "version": "0.5.27", + "version": "0.6", "author": "Kitematic", "description": "Simple Docker Container management for Mac OS X.", "homepage": "https://kitematic.com/", From fa73459f73a6027c15b6107c4c462c16622e2170 Mon Sep 17 00:00:00 2001 From: Justin Leveck Date: Tue, 26 May 2015 14:15:02 -0700 Subject: [PATCH 02/27] Fix typo in FAQ Fixes typo in FAQ to increase readability. --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index ada4fa5c..0fef59e2 100755 --- a/docs/faq.md +++ b/docs/faq.md @@ -19,7 +19,7 @@ best way to start contributing to Kitematic is to review our doc on ### How does Kitematic work with Docker? -Kitematic connects directly do a running instance of Docker and controls it via +Kitematic connects directly to a running instance of Docker and controls it via the Docker Remote API. ### Which platforms does Kitematic support? From aa2e55f9b78fe54a933a973a5b9b8110f5c151df Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Tue, 26 May 2015 14:28:13 -0700 Subject: [PATCH 03/27] Bump version to 0.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46c56405..88842835 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Kitematic", - "version": "0.6", + "version": "0.6.0", "author": "Kitematic", "description": "Simple Docker Container management for Mac OS X.", "homepage": "https://kitematic.com/", From d84028fcdbbfbedbea6dc9afcbcb4021b399d2c3 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 26 May 2015 15:03:09 -0700 Subject: [PATCH 04/27] New icons. --- images/feedback.png | Bin 671 -> 899 bytes images/feedback@2x.png | Bin 1369 -> 1966 bytes images/preferences.png | Bin 624 -> 1175 bytes images/preferences@2x.png | Bin 1259 -> 2172 bytes images/user.png | Bin 931 -> 841 bytes images/user@2x.png | Bin 1910 -> 1830 bytes images/whaleicon.png | Bin 711 -> 1064 bytes images/whaleicon@2x.png | Bin 1223 -> 2184 bytes styles/left-panel.less | 7 ++----- 9 files changed, 2 insertions(+), 5 deletions(-) diff --git a/images/feedback.png b/images/feedback.png index f4a0d8251da1e769996fb90089ab8cb667bfd56c..ce9dc049888efd1bc5de0a1a0e5102919049fcb0 100644 GIT binary patch literal 899 zcmV-}1AP36P)Px&JxN4CR5%f>RZU1#Q53%CyeDZEEm{Pw0~N9&3$-L@k&q%4Qq-zNNVX`)Oy{Q@ z-#9YkNIK&pNP-|J0-=>)i-HP@ED|!IKU#()v}mw}gYVwkIZy8}j=yAgbI-ZwobTOt ze!dH0?FB*SRykn7evPVxT|wcrR`Va?&h^iv>ea$wC4=AJw*$9tX(pIUWVb1NTxgi~ zd_k885Y;5RggdNeGj|h-Ksq018E~gFP;Fb*2wi0Yr09-0zK{7qtcRS`UTuj80aUtD zp6z$q$8-Ib00(=LM*#7a)}kTa)jF2zxSAY_3>?#z{a7f~7!S9-Hhx)PzNux~V_J#h zec{##-;+!(57f@XM3(@MZ0Y3$LQ)lu~{gJ^& zwxNYr#8&u8ol}bP3IfpBqO=M#fDQ0KDb-9lKB`@}6a|d%9~p43V=R2= zYF!q;>8lf3T?Mp&#cM38l9`TK?O=bcH38IMKpi)N&?fRlYsbXs^U)KqHp+VGT@85_n2zi+Q*~MXWl?j@2~fm Z{sjY%gCt}|RV4rb002ovPDHLkV1i*9t4{y` literal 671 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 A3jhEB literal 1369 zcmV-f1*ZCmP)Px)6G=otR9FekSY3!!RTN%(pShV4r6s`>mJmKzQ4tszr9==&KN7?k^kO|s(97I0 z()sV${M>OU@A%NmJd^~1jZgOT5=kh5^amN0L&*84c_taU z2hQDVuf5j#zO#SVzC>;InE%437?)RFXZ_>OnDvHir!oFk#PQyo@#N;M_dlO^=9B5T zcVVgVa}(n- zS#QRf$errAq|(zb&iKK}q2et2G1ul#OG3TzzMHP?u(O8DV_^tS{*?FrFgqV3Z%$vd z$(cf>!&vJ($@tqCakDXI8~d%R@jLQQ#dVeAoqvYnl4A&`lTJ=!dmk-_u4HIkLXIh+&Rz}g6i#_ANO)6&F-ni%2+zc8R?vD50 z9(DM`yeRIMX6~sAN%COr@Yxz)gELa6fC2e&S8=UA&N?(;&5FD|>thVyh1@ft}S=kWDY$XRw-d0>2uUA0T7i@`hG$ zchAbpGIY|W0n##$Jz~p>g%4v^H{5D~tcPR=PJ?1;t5}HavplX5IeN1++_N1o59dDU z(57};=C%(oLTn*~vx%9?{J^Fc?lTO|ox)R!NahxRUE&UkPMVZTwajY|3}A^DV+#ka z2q7Gl{KYbk9FUjh;!_$a4w>`5b8@8T8`Vz5JHLhwZK~69DfWs5Y;ZsfA%s&~19Iar zmDAEsOcZ~s(NU`7j;ecd+lN@nK?qr6Bz=(3d^XiVESDm{QVv3h@j4X~2c^o(UDjX; z2PKqYgvz8-IlI(N01e~5)_69I*g^L}xdIG+iTUKxAi zj#bg>(|93=ZF%ID{s9(JU&Iqa$bmIDFPqIOqbyML5bsep;JwC0&xCDxWbsM;C05`R zVkrk9goKS8rdtfo~I0b!dUQCEMS8JbV5jO2a=HEXff*~(?csi zC3o%%-lylPHM4bKbbn7(zVdI?)@&6^jv=v9H(+EbE@SHrMF>@GJQDEg!)d3A6vvLg zV2{@MkS#ONm~Qo|4@P{%G%dgTJ2Y^c$inwy$rAhzC3(qz4PCh3l~41ob3M#I(@1=12S}<=$a(? zb%bEtR@Wf?qPDsyDyg=*N-HTY+vm@QfE2aU-!UOCk+Bo&A699mrwQIXGKZ`A!>SJK b|5p49*5l>%XgonI00000NkvXXu0mjfZK9`^ diff --git a/images/preferences.png b/images/preferences.png index c533e97dd9a5f69a2cd7925dee12f2dfcef6d1b9..e0bdc2f32e94b133f61db09e8ca8daa999ba30aa 100644 GIT binary patch literal 1175 zcmV;I1Zew-P)Px(QAtEWR5%fpRc~lpRTMwxzGO>GyLIW<+@zpeozP+((+{f?WZ(xsi3s(BqAJ#e}2p7T4ud+xdC+=uWV#Ed0h02><}s8H#6IC$yb+{8Zt0y0^r^=2g5iXh%m zh&B)Y?v0&&RNL2LwT|b%5r<;Q=e-7wx3#qyYk*f1{avSdD5a*go-u^I$Ua)9=PF_b zpb}>QaHX;3z@^^a#Ab@JLjm};10Ze@$`xcAVJ;K)4*RSpuMh`cJ9m#mYONg1-unJ9 zAZ#^iJTn4u5%T%U(dqj!05vaayq^)N-@%d(`!a_P0G$shg=uX04ngHIw{AQ!F)^{y z+1a_#Q@^WuL@5^c%2T-$p_a~qrV=oks4Go3n8COZg z@Nn;)1uJ)iqHZ>7cX3V~Qi|+l@cC{UE-}dieZGttO&ujWr5=z^1q%Je+xB5iN_xi` zbotPwbRa@uFx+*7jZ8r7vBiRFNeu>nW!*_Re7D=!FhjN1pBU&mU&ehzxUVdk;G^>KIl7h7(vA_?^BX&83G^j*+~vg^gl%MOP@eO94RMu@ zkU_*&1@?&&Lb_Gd^`pQ6it>Y^WgRV-6mZRY41;sKpT>21 zgr2J3xo0;R?#~t4-HCAUUEaKsinulZu|jnM4A+;fuDVa@c=wn7C~l%Cavqm(I*J{* z5lA*e>~CnAT2ER<%r8=+H2)q&{k~PQLzLU+`27H-E>dY_7|cS|kg?I4nviml z9vy0Ve5hEo9?_Amq5zx*(F-Pz103&^k|M2={bnR}nl;?A+TuJqQtpMPx%DoI2^R5%fpQcG)7Q4pRvw>Dxap&JzuH-c*^xNzeS5J5$-q6-TZsR;JAr1d5w z^(HCFm6SX{7mD}*K}Fs916&uxAD}B2RYVl6(rS}4esjaQq(Vv@ILypvMX zEzIm!mioL9-rQ$6brivSjN#h~s#t5MqQ%+!T@M9Ht#g>s6X&DIoVE1fkJni--cV}N zc>JO_0eW4F?DvOB0F27w%u{srIl-9g8ke%(^p-D92x^33-0Bvrk7G90?IW_C2@-qF zar9e*QsbiYRp(0ev&_8PVM2CZ%34-dF8QHZ8@4uF9qutrt2r>H+*>dxQu#86e*?1pvOU<`v_Ar9qRSNzg|F0000< KMNUMnLSTYq(k+<) diff --git a/images/preferences@2x.png b/images/preferences@2x.png index 3aba6c049ec6681cf69394578d0c26bbd68a756e..2b8eda4f6bb94af71564138c8afe2a4634238487 100644 GIT binary patch literal 2172 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 V%fpA{+ynps002ovPDHLkV1jexXX*d| diff --git a/images/user.png b/images/user.png index 82cae572a0553164169b0d17786871344f52db80..8ecbd702f5a4bb50c876f441b69a1bdb9fd5d04f 100644 GIT binary patch literal 841 zcmV-P1GfB$P)Px&14%?dR5%fhRZU1#Q53%C-WOwk2(?PuwrF8SQ#4@3=ljk#_nmvr z84~|~DC<5vOmfFjBXt9)q~)T~e?IlQcfRn}#D!BWAd?xWmwOY}S>^`g4u?+*LyG~I zOoJeiV%uZg5xufLS}1h=uyv}0)9zr(QR*2VWrlpw)92p$YzJZA?LIzYl;~xFr04sW zif-q0l($7Vn;&W>Dc>0*F7)4PABz&>?C##dGe$Yjh1M7Qa~+c*uOf_-D#sZ!TAUro zwa~8!$~Q{N6+(4g(nY$kyEv&Zcb?bYF|(1+o)LDEgV!TQ6v&A@blM9`2Kpj z=w=q8yiD)Vc_nGY|FzbLoJ)YXDCD%3sG}0IM0A-i@&I1g@Zkre!iAoWm(VC(I%_gW zWaLe4bS_GSjgvCE&-TL?U>1POE>{vs)Ttq(3c1^J7LVggpKtrIuZ5K>$bqIbj%wmM zeP1h>{X1*=;f%w$=Fw168fxI&l#1V0A@Rm`RrYZhHxjxuxV#G4GFDf0JD+Uca^tk~ z0agWUI;1AE$Tb(tflYVGTKGEkovo*~AHFhH4ROn3o=EciS?>LlHY1zu+kdF3`2%Bj zZ45qO;MBlU7*Y~biVXRg{G-N@)Z)61*tL6{@BUcmt6mvnPQWdLm>+C<&_s@nA^k*> z%!k1#S$~DgDH-nLR&c-#aSSDv8{xePE)S!R^PJ4yA8rLn619co?N%ar4IB(3Xg~{l zwo6YiE*)n|YjK>U7-yh5e<3-ta;Yxy;5x@KuYJ#J-7%7S@&$iM9SMqWjxc~% z9!hJRk~*XH>FC(pQpW)BtIS{FcR3OtXD$meKQS(&q97|fVshfuLi351QA()ad}>q* zaYJkv-muMOFIL&wV0+03UF4j$6(6L(**cXR+dz3A{F!2&p!MMk8j5RwyFb&vRM{~z T8J<>r00000NkvXXu0mjf?oNy@ literal 931 zcmV;U16=%xP)Px&T}ebiR5%fhRC{QRVHkg&_uH{q%p7Ai^r{WmbcD%zUTJ)-rsZi znErC|^Yg8RIeFQN?JQz7fmuF^*1eJb-Uop|Ao`~?{?%C1(41)z7ZZz*h|@*r9WzZD zkrN?%;5%#E(Z(wOt{!)O0$AOV=4=35XA#)>Ju#iqB#+IFpl8B3S1D^Vkt`9S0WGp= zpRe$y0~iN85NurOQJz~Sh$LE6;oEs}B#1%F>Q77ayt;QU(%RZ;*9K2+0O%zW`b;{y zz1+X^iiwSZf!YGabccz@Xt9@8`ieV@ue!cvNs>h!Lh=@YL$LJ%;CQ*O@N8YMaXPc- zArQPyP7JKBp}CEj=S8EkuBx=~K5n8?#!n6bFWJ1&eNeOawyif*l@{Htt8bY_7PW)+ zi%0D@a#YQc6RQBULTi260GY&5X<5rbH|z$9KeLQhinEMf;Vw4oWqOzNYQ$Q!1drAsw^vh@-s2 zZBBrZJlYxyk(pp4nZ&k?bK6EGsV%6lSF>DZ^L5D1&AX2_O&N~JGRq_Lann8M+8j)N z24spWc?d7>Lu@zbo(PAzJvo{0LLYqH9a@AY5Y+}-a+NZZ99x;MkX~c|=P`T9G6o!m zP~eSb;mw>;Wl6yud>KGfutNU^P4d7?SQ}FqZ8+r-vO9EWuHEhg3$l~002ovPDHLk FV1k#sz(N23 diff --git a/images/user@2x.png b/images/user@2x.png index 0d0991cece1b06e326f1497a39107f98fd42baef..3d9b9cd2fa3e8c47ca9f3cc0a242f21865084d23 100644 GIT binary patch literal 1830 zcmV+>2if?EP)Px*;7LS5R9FesnO}$%RUF69nYrs-|Ad=Sv>GeIMpP(0WEmQQ4?gsuq(q@Y6oEug zrlzj7GP>fjrHlI%D^Ua*N+`HNLJ>)>MA<`BD%g@}wL(#?n49a~nbY@sX3p%~JAd!4 z``|%$W`5`Q`<>66`JI2iE5vP9bU25?~ez*F5stz#P8De2Cs^1gENMwN_$$VS=knPUChDDJt?JFA%tw!c1n4;9&}yV z-sQY@+4q(Iw-E3%jx(jzn%M!ySJ8N*5@G}&yjOVQqs|>0zC|+-6)LiA*Z#+ZCDs6Z zJsK~=@&?R%es+g;eC#+k^StB&x3%rLTTYvH3_ZF8@#rZb58afb?fc%^d@0X)R{f^k zd*@D34INUbwfbu*)vtz!S9Nx7|1--j6L`C`e}S-NA9{5z2FzvG^;W;_Z2T_EVZC)* zobE?$+d7JY+k)P{BwV#(kF(*2G(V}p0qkkO&H(J`QFnCJUgwQJ(i}}hzS()_o(8+& z7@!ve`d>gVPJ<2xPIYq(gP>;#dw9SdS~gj*Y?;2<2HRo>v2D#zjisOLS{Vn}UFADI zMO-al&%)8uMFvBypL(CqojmC_FJ1J>EZMjWJw0DGG(2(d(nW_TkNPS_A9&B%fCCJ$ zml*~{VKFy9jJf$GjQ-_VI9lin3kRkv^%>^e_b}(4r7WwkEriD^gvS{`FS*}t+6Db> zQJbn5<~(ba#09BTL&fzTFEYUNlxN@BjnV$H9_>-@=H8!O-W_oN*;u3lI1o#=^$lMB zrt69aqVsfB40BPy88G>X~!`xJEru{=*R!kq?ICGMhti(MBlyw59U>dMng zs;|Qqv#VwjhS3iRB_5<>bp2OJ4J6A{C0SlXTHID|Tj?@j^nrO&K=Gu<(?OwvY3E`g z#Uv#uen}E1%CN@{?9RYMC^! zKHb8IXRr+0Sk>RZo@>Kt`14prih#O*{dRVHN_C>xFd0U_hyA0t&(1_#mL(2Dab}KcteQ5orH@!;T!0OpS%no>VINp$V33gkau7{?i7E+^r<$fay&AekhRYQ zTc1I$CzECibVA^u%MbF+nUSgW!Jfe8``KFgM4#z1sh9n%kp7YfO*pWv5SR~4%wg#q zfs?g72vTNBxzSoPp|~}UYOjcA?K>i8+hjoO-XK$?sv20IPCc&&U>FnDQD$U}GNz=Z z=KfY+qrTZD+a?3HDm~E?Guy4|VG0JktL=!Je#|E=Odpw3E>F2SPk-#}%k32A^2(NWJK6fUXZ z>kE@InTfzes7(d}{t*CApEzFJ1Awms@_WGMCIeG}BhWhCiceITltIUajPC;J)>sTj z-=8T@ej3ITVKIZ?->og$Cw#LFww0Dtgyy zXJjN3Fm)7cWVkoravNR2ih8K4hm)LgHql8AKW~uw!y*FcysU`6yckVt*9< UkL<%Cu>b%707*qoM6N<$f(WZ__5c6? literal 1910 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 diff --git a/images/whaleicon@2x.png b/images/whaleicon@2x.png index 941ed32fe756a8dd0ce3a8f332906ebabd71ba25..de6ff361a1942b41fa3abd1a293cca30adbf96dc 100644 GIT binary patch literal 2184 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 Date: Tue, 26 May 2015 15:56:04 -0700 Subject: [PATCH 05/27] text case fix - I've verified my email address --- src/components/Header.react.js | 2 +- src/components/NewContainerSearch.react.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Header.react.js b/src/components/Header.react.js index cc54ce98..36f7a48a 100644 --- a/src/components/Header.react.js +++ b/src/components/Header.react.js @@ -74,7 +74,7 @@ var Header = React.createClass({ let menu = new Menu(); if (!this.state.verified) { - menu.append(new MenuItem({ label: 'I\'ve Verified My Email Address', click: this.handleVerifyClick})); + menu.append(new MenuItem({ label: 'I\'ve verified my email address', click: this.handleVerifyClick})); } menu.append(new MenuItem({ label: 'Sign Out', click: this.handleLogoutClick})); diff --git a/src/components/NewContainerSearch.react.js b/src/components/NewContainerSearch.react.js index 95988559..159c71b5 100644 --- a/src/components/NewContainerSearch.react.js +++ b/src/components/NewContainerSearch.react.js @@ -126,7 +126,7 @@ module.exports = React.createClass({

Please verify your Docker Hub account email address

- {spinner} + {spinner}
From e9ce513c23d84caf461b5ee8f6f93de299db939d Mon Sep 17 00:00:00 2001 From: Michael Chiang Date: Tue, 26 May 2015 16:03:15 -0700 Subject: [PATCH 06/27] text fix - verification text fix - verification --- src/components/Header.react.js | 2 +- src/components/NewContainerSearch.react.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Header.react.js b/src/components/Header.react.js index 36f7a48a..cc54ce98 100644 --- a/src/components/Header.react.js +++ b/src/components/Header.react.js @@ -74,7 +74,7 @@ var Header = React.createClass({ let menu = new Menu(); if (!this.state.verified) { - menu.append(new MenuItem({ label: 'I\'ve verified my email address', click: this.handleVerifyClick})); + menu.append(new MenuItem({ label: 'I\'ve Verified My Email Address', click: this.handleVerifyClick})); } menu.append(new MenuItem({ label: 'Sign Out', click: this.handleLogoutClick})); diff --git a/src/components/NewContainerSearch.react.js b/src/components/NewContainerSearch.react.js index 159c71b5..8b18ce97 100644 --- a/src/components/NewContainerSearch.react.js +++ b/src/components/NewContainerSearch.react.js @@ -126,7 +126,7 @@ module.exports = React.createClass({

Please verify your Docker Hub account email address

- {spinner} + {spinner}
From 7f9bd170a95e4ceead7d2815e8784df13699991a Mon Sep 17 00:00:00 2001 From: Michael Chiang Date: Tue, 26 May 2015 16:13:28 -0700 Subject: [PATCH 07/27] Consistent text. Consistent text. --- src/components/AccountLogin.react.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AccountLogin.react.js b/src/components/AccountLogin.react.js index d189f1c7..427c2725 100644 --- a/src/components/AccountLogin.react.js +++ b/src/components/AccountLogin.react.js @@ -67,9 +67,9 @@ module.exports = React.createClass({ let loading = this.props.loading ?
: null; return (
- +

{this.state.errors.username}

- +

{this.state.errors.password}

Forgot your password?

{this.state.errors.detail}

From 12be1c7dd4d7b64f5d8692e90fbaf73874a365e7 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 26 May 2015 17:09:01 -0700 Subject: [PATCH 08/27] Tweaked positive button. --- src/components/ImageCard.react.js | 2 +- styles/theme.less | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/ImageCard.react.js b/src/components/ImageCard.react.js index 5a94d488..8f9be4bb 100644 --- a/src/components/ImageCard.react.js +++ b/src/components/ImageCard.react.js @@ -169,7 +169,7 @@ var ImageCard = React.createClass({ {this.state.chosenTag} diff --git a/styles/theme.less b/styles/theme.less index d20daccc..e5bda861 100644 --- a/styles/theme.less +++ b/styles/theme.less @@ -193,6 +193,16 @@ input[type="text"] { } .btn-positive { .btn-styles(@brand-positive); + &:hover, + &:focus { + border-color: darken(@brand-positive, 7%); + color: darken(@brand-positive, 7%); + } + &:active { + background-color: lighten(@brand-positive, 53%); + border-color: darken(@brand-positive, 7%); + color: darken(@brand-positive, 7%); + } } .btn-default { .btn-styles(@btn-default-bg); } .btn-primary { .btn-styles(@btn-primary-bg); } From 5bf9635ef4c884350fc01d7a89f3e211c6b3ff43 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 26 May 2015 17:43:06 -0700 Subject: [PATCH 09/27] Added a new gray color. --- styles/container-home.less | 2 +- styles/container-settings.less | 6 +++--- styles/left-panel.less | 2 +- styles/variables.less | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/styles/container-home.less b/styles/container-home.less index 8a11e5d8..66232d04 100644 --- a/styles/container-home.less +++ b/styles/container-home.less @@ -55,7 +55,7 @@ flex: 1 auto; display: flex; font-size: 10px; - color: @gray-lightest; + color: @gray-light; .label-left { flex: 0 auto; min-width: 60px; diff --git a/styles/container-settings.less b/styles/container-settings.less index 46e692a5..13510553 100644 --- a/styles/container-settings.less +++ b/styles/container-settings.less @@ -72,7 +72,7 @@ .env-vars-labels { width: 100%; font-size: 12px; - color: @gray-lightest; + color: @gray-light; margin-left: 5px; margin-bottom: 5px; margin-top: 20px; @@ -116,7 +116,7 @@ flex: 1 auto; display: flex; font-size: 12px; - color: @gray-lightest; + color: @gray-light; .label-left { flex: 0 auto; min-width: 85px; @@ -164,7 +164,7 @@ flex: 1 auto; display: flex; font-size: 12px; - color: @gray-lightest; + color: @gray-light; .label-left { flex: 0 auto; margin-right: 30px; diff --git a/styles/left-panel.less b/styles/left-panel.less index 4bd82879..4fe83129 100644 --- a/styles/left-panel.less +++ b/styles/left-panel.less @@ -153,7 +153,7 @@ color: @gray-darkest; } .image { - color: @gray-lighter; + color: @gray-light; font-size: 10px; font-weight: 400; text-overflow: ellipsis; diff --git a/styles/variables.less b/styles/variables.less index 64cbc2b8..83e17a8c 100644 --- a/styles/variables.less +++ b/styles/variables.less @@ -15,6 +15,7 @@ @gray-darkest: #233137; @gray-darker: #556473; @gray-normal: #7A8491; +@gray-light: #9AA7BB; @gray-lighter: #C4CDDA; @gray-lightest: #E1E8EF; From f47d29d05071bb1fa5cf7f1a3c484d4ffb234d94 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 26 May 2015 17:47:37 -0700 Subject: [PATCH 10/27] Fix scroll clipping. --- styles/new-container.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/new-container.less b/styles/new-container.less index f6dfb928..88109b5b 100644 --- a/styles/new-container.less +++ b/styles/new-container.less @@ -50,8 +50,8 @@ flex-direction: row; justify-content: flex-end; font-size: 13px; - margin-bottom: 10px; margin: 0 20px; + margin-bottom: 10px; .results-filter { text-align: center; From 57f04f5c3920ae56c9aa2556b414d5444343d0e6 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Tue, 26 May 2015 17:50:58 -0700 Subject: [PATCH 11/27] Added hover color for tabs. --- styles/new-container.less | 4 ++++ styles/right-panel.less | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/styles/new-container.less b/styles/new-container.less index f6dfb928..1247da1e 100644 --- a/styles/new-container.less +++ b/styles/new-container.less @@ -57,6 +57,10 @@ text-align: center; margin: 0 10px; min-width: 40px; + &:hover { + border-radius: 40px; + background-color: @gray-lightest; + } } .results-filter-title { diff --git a/styles/right-panel.less b/styles/right-panel.less index d8dfba88..3ceb91d2 100644 --- a/styles/right-panel.less +++ b/styles/right-panel.less @@ -119,6 +119,10 @@ background-color: transparent; } } + &:hover { + border-radius: 40px; + background-color: @gray-lightest; + } } .details-progress { From 5af7c74381f04d8477afec4f90113d9f73ba141f Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Tue, 26 May 2015 18:07:26 -0700 Subject: [PATCH 12/27] Removing coverage for now --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a9888c78..78c160f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,3 @@ cache: directories: - resources - node_modules - -after_success: - - which ./node_modules/coveralls/bin/coveralls.js && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js From a3fb14462a27957d38cebe3e9cc5e4df2b72a345 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Tue, 26 May 2015 18:49:23 -0700 Subject: [PATCH 13/27] Fixing jest tests, adding integration tests --- __integration__/HubUtil-integration.js | 23 +++++++++++++++++++ __integration__/RegHubUtil-integration.js | 9 ++++++++ {src/stores => __tests__}/SetupStore-test.js | 12 +++++----- {src/utils => __tests__}/URLUtil-test.js | 6 ++--- {src/utils => __tests__}/Util-test.js | 4 ++-- .../VirtualBoxUtil-test.js | 6 ++--- jest-integration.json | 19 +++++++++++++++ package.json | 11 +++------ 8 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 __integration__/HubUtil-integration.js create mode 100644 __integration__/RegHubUtil-integration.js rename {src/stores => __tests__}/SetupStore-test.js (91%) rename {src/utils => __tests__}/URLUtil-test.js (95%) rename {src/utils => __tests__}/Util-test.js (98%) rename {src/utils => __tests__}/VirtualBoxUtil-test.js (77%) create mode 100644 jest-integration.json diff --git a/__integration__/HubUtil-integration.js b/__integration__/HubUtil-integration.js new file mode 100644 index 00000000..d6638c35 --- /dev/null +++ b/__integration__/HubUtil-integration.js @@ -0,0 +1,23 @@ +jest.autoMockOff(); + +describe('HubUtil Integration Tests', () => { + describe('token refresh', () => { + it('re-auths if the token has expired', () => { + expect(true).toBe(true); + }); + }); + + describe('signup', () => { + it('returns a 204 and sets localstorage data', () => { + }); + }); + + describe('login', () => { + it('Returns a 401 with account not active string if not active', () => { + + }); + it('Returns a 401 if the password is wrong', () => { + + }); + }); +}); diff --git a/__integration__/RegHubUtil-integration.js b/__integration__/RegHubUtil-integration.js new file mode 100644 index 00000000..782a4990 --- /dev/null +++ b/__integration__/RegHubUtil-integration.js @@ -0,0 +1,9 @@ +jest.autoMockOff(); + +describe('RegHubUtil Integration Tests', () => { + describe('repos', () => { + it('returns set of repos', () => { + + }); + }); +}); diff --git a/src/stores/SetupStore-test.js b/__tests__/SetupStore-test.js similarity index 91% rename from src/stores/SetupStore-test.js rename to __tests__/SetupStore-test.js index 5613d44a..3da50458 100644 --- a/src/stores/SetupStore-test.js +++ b/__tests__/SetupStore-test.js @@ -1,9 +1,9 @@ -jest.dontMock('./SetupStore'); -var setupStore = require('./SetupStore'); -var virtualBox = require('../utils/VirtualBoxUtil'); -var util = require('../utils/Util'); -var machine = require('../utils/DockerMachineUtil'); -var setupUtil = require('../utils/SetupUtil'); +jest.dontMock('../src/stores/SetupStore'); +var setupStore = require('../src/stores/SetupStore'); +var virtualBox = require('../src/utils/VirtualBoxUtil'); +var util = require('../src/utils/Util'); +var machine = require('../src/utils/DockerMachineUtil'); +var setupUtil = require('../src/utils/SetupUtil'); describe('SetupStore', function () { describe('download step', function () { diff --git a/src/utils/URLUtil-test.js b/__tests__/URLUtil-test.js similarity index 95% rename from src/utils/URLUtil-test.js rename to __tests__/URLUtil-test.js index cfa13777..2c121252 100644 --- a/src/utils/URLUtil-test.js +++ b/__tests__/URLUtil-test.js @@ -1,7 +1,7 @@ -jest.dontMock('./URLUtil'); +jest.dontMock('../src/utils/URLUtil'); jest.dontMock('parseUri'); -var urlUtil = require('./URLUtil'); -var util = require('./Util'); +var urlUtil = require('../src/utils/URLUtil'); +var util = require('../src/utils/Util'); describe('URLUtil', function () { beforeEach(() => { diff --git a/src/utils/Util-test.js b/__tests__/Util-test.js similarity index 98% rename from src/utils/Util-test.js rename to __tests__/Util-test.js index 471b1088..985d05bd 100644 --- a/src/utils/Util-test.js +++ b/__tests__/Util-test.js @@ -1,5 +1,5 @@ -jest.dontMock('./Util'); -var util = require('./Util'); +jest.dontMock('../src/utils/Util'); +var util = require('../src/utils/Util'); describe('Util', function () { describe('when removing sensitive data', function () { diff --git a/src/utils/VirtualBoxUtil-test.js b/__tests__/VirtualBoxUtil-test.js similarity index 77% rename from src/utils/VirtualBoxUtil-test.js rename to __tests__/VirtualBoxUtil-test.js index 7af88edd..3bf9a442 100644 --- a/src/utils/VirtualBoxUtil-test.js +++ b/__tests__/VirtualBoxUtil-test.js @@ -1,6 +1,6 @@ -jest.dontMock('./VirtualBoxUtil'); -var virtualBox = require('./VirtualBoxUtil'); -var util = require('./Util'); +jest.dontMock('../src/utils/VirtualBoxUtil'); +var virtualBox = require('../src/utils/VirtualBoxUtil'); +var util = require('../src/utils/Util'); describe('VirtualBox', function () { it('returns the right command', function () { diff --git a/jest-integration.json b/jest-integration.json new file mode 100644 index 00000000..92b8bff6 --- /dev/null +++ b/jest-integration.json @@ -0,0 +1,19 @@ +{ + "testDirectoryName": "__integration__", + "scriptPreprocessor": "/util/preprocessor.js", + "setupEnvScriptFile": "/util/testenv.js", + "setupTestFrameworkScriptFile": "/util/prepare.js", + "unmockedModulePathPatterns": [ + "alt", + "stream", + "tty", + "net", + "crypto", + "babel", + "/node_modules/.*JSONStream", + "/node_modules/object-assign", + "/node_modules/underscore", + "/node_modules/bluebird", + "/node_modules/source-map-support" + ] +} diff --git a/package.json b/package.json index 88842835..42cb5efe 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "scripts": { "start": "gulp", "test": "jest", + "integration": "jest -c jest-integration.json", "release": "gulp release", "release:beta": "gulp release --beta", "lint": "jsxhint src", @@ -28,12 +29,6 @@ "scriptPreprocessor": "/util/preprocessor.js", "setupEnvScriptFile": "/util/testenv.js", "setupTestFrameworkScriptFile": "/util/prepare.js", - "collectCoverage": true, - "testDirectoryName": "src", - "testPathIgnorePatterns": [ - "/node_modules/", - "^((?!-test).)*$" - ], "unmockedModulePathPatterns": [ "alt", "stream", @@ -66,8 +61,8 @@ "classnames": "^1.2.0", "coveralls": "^2.11.2", "deep-extend": "^0.4.0", - "dockerode": "^2.1.4", "exec": "0.2.0", + "dockerode": "^2.1.4", "install": "^0.1.8", "jquery": "^2.1.3", "mixpanel": "0.2.0", @@ -102,7 +97,7 @@ "gulp-shell": "^0.4.1", "gulp-sourcemaps": "^1.5.2", "gulp-util": "^3.0.4", - "jest-cli": "kitematic/jest", + "jest-cli": "^0.4.5", "jsxhint": "^0.14.0", "minimist": "^1.1.1", "react-tools": "^0.13.1", From 92e996b12e4204d63fcde86cb86709b932f55b88 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Tue, 26 May 2015 18:51:52 -0700 Subject: [PATCH 14/27] Adding config file for unit tests --- jest-unit.json | 18 ++++++++++++++++++ package.json | 20 +------------------- 2 files changed, 19 insertions(+), 19 deletions(-) create mode 100644 jest-unit.json diff --git a/jest-unit.json b/jest-unit.json new file mode 100644 index 00000000..0981c13e --- /dev/null +++ b/jest-unit.json @@ -0,0 +1,18 @@ +{ + "scriptPreprocessor": "/util/preprocessor.js", + "setupEnvScriptFile": "/util/testenv.js", + "setupTestFrameworkScriptFile": "/util/prepare.js", + "unmockedModulePathPatterns": [ + "alt", + "stream", + "tty", + "net", + "crypto", + "babel", + "/node_modules/.*JSONStream", + "/node_modules/object-assign", + "/node_modules/underscore", + "/node_modules/bluebird", + "/node_modules/source-map-support" + ] +} diff --git a/package.json b/package.json index 42cb5efe..25ce4dd1 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "bugs": "https://github.com/kitematic/kitematic/issues", "scripts": { "start": "gulp", - "test": "jest", + "test": "jest -c jest-unit.json", "integration": "jest -c jest-integration.json", "release": "gulp release", "release:beta": "gulp release --beta", @@ -25,24 +25,6 @@ "url": "http://www.apache.org/licenses/LICENSE-2.0.html" } ], - "jest": { - "scriptPreprocessor": "/util/preprocessor.js", - "setupEnvScriptFile": "/util/testenv.js", - "setupTestFrameworkScriptFile": "/util/prepare.js", - "unmockedModulePathPatterns": [ - "alt", - "stream", - "tty", - "net", - "crypto", - "babel", - "/node_modules/.*JSONStream", - "/node_modules/object-assign", - "/node_modules/underscore", - "/node_modules/bluebird", - "/node_modules/source-map-support" - ] - }, "docker-version": "1.6.2", "docker-machine-version": "0.2.0", "electron-version": "0.26.0", From e55a8f0add65ba826ada8cfd65062180f950a332 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Tue, 26 May 2015 18:52:42 -0700 Subject: [PATCH 15/27] Removing unnecessary config entries for integration tests --- jest-integration.json | 9 --------- 1 file changed, 9 deletions(-) diff --git a/jest-integration.json b/jest-integration.json index 92b8bff6..1405f904 100644 --- a/jest-integration.json +++ b/jest-integration.json @@ -4,16 +4,7 @@ "setupEnvScriptFile": "/util/testenv.js", "setupTestFrameworkScriptFile": "/util/prepare.js", "unmockedModulePathPatterns": [ - "alt", - "stream", - "tty", - "net", - "crypto", "babel", - "/node_modules/.*JSONStream", - "/node_modules/object-assign", - "/node_modules/underscore", - "/node_modules/bluebird", "/node_modules/source-map-support" ] } From dedf1d61a70866852fd60c7e4a01f99d17f3a986 Mon Sep 17 00:00:00 2001 From: TeckniX Date: Wed, 27 May 2015 10:50:50 -0400 Subject: [PATCH 16/27] Modified docker cli to use proper shell --- src/utils/DockerMachineUtil.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/DockerMachineUtil.js b/src/utils/DockerMachineUtil.js index 98399d3c..66bd3921 100644 --- a/src/utils/DockerMachineUtil.js +++ b/src/utils/DockerMachineUtil.js @@ -156,7 +156,7 @@ var DockerMachine = { }); } else { this.info().then(machine => { - var cmd = [resources.terminal(), `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(util.home(), '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 $SHELL`]; + var cmd = [resources.terminal(), `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(util.home(), '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 /bin/bash`]; util.exec(cmd).then(() => {}); }); } From ee5ad39667b1b0f54f361e740090192782b06e02 Mon Sep 17 00:00:00 2001 From: TeckniX Date: Wed, 27 May 2015 13:58:06 -0400 Subject: [PATCH 17/27] Patched warnings and random port assignment Signed-off-by: TeckniX --- src/actions/ContainerActions.js | 20 ++++++++++++------- .../ContainerDetailsSubheader.react.js | 5 +++-- src/utils/DockerMachineUtil.js | 2 +- src/utils/DockerUtil.js | 2 ++ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/actions/ContainerActions.js b/src/actions/ContainerActions.js index e5fd4e1d..d3e5996d 100644 --- a/src/actions/ContainerActions.js +++ b/src/actions/ContainerActions.js @@ -2,10 +2,6 @@ import alt from '../alt'; import dockerUtil from '../utils/DockerUtil'; class ContainerActions { - start (name) { - this.dispatch({name}); - dockerUtil.start(name); - } destroy (name) { this.dispatch({name}); @@ -17,14 +13,24 @@ class ContainerActions { dockerUtil.rename(name, newName); } + start (name) { + this.dispatch({name}); + dockerUtil.start(name); + } + stop (name) { this.dispatch({name}); dockerUtil.stop(name); } - update (name, container) { - this.dispatch({name, container}); - dockerUtil.updateContainer(name, container); + restart (name) { + this.dispatch({name}); + dockerUtil.restart(name); + } + + update (name, containerOpts) { + this.dispatch({name, containerOpts}); + dockerUtil.updateContainer(name, containerOpts); } clearPending () { diff --git a/src/components/ContainerDetailsSubheader.react.js b/src/components/ContainerDetailsSubheader.react.js index 9b4cda57..8ab70738 100644 --- a/src/components/ContainerDetailsSubheader.react.js +++ b/src/components/ContainerDetailsSubheader.react.js @@ -83,7 +83,8 @@ var ContainerDetailsSubheader = React.createClass({ handleRestart: function () { if (!this.disableRestart()) { metrics.track('Restarted Container'); - dockerUtil.restart(this.props.container.Name); + //dockerUtil.restart(this.props.container.Name); + containerActions.restart(this.props.container.Name); } }, handleStop: function () { @@ -223,7 +224,7 @@ var ContainerDetailsSubheader = React.createClass({
Restart - {{startStopToggle}} + {startStopToggle}
Terminal diff --git a/src/utils/DockerMachineUtil.js b/src/utils/DockerMachineUtil.js index 66bd3921..98399d3c 100644 --- a/src/utils/DockerMachineUtil.js +++ b/src/utils/DockerMachineUtil.js @@ -156,7 +156,7 @@ var DockerMachine = { }); } else { this.info().then(machine => { - var cmd = [resources.terminal(), `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(util.home(), '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 /bin/bash`]; + var cmd = [resources.terminal(), `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(util.home(), '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 $SHELL`]; util.exec(cmd).then(() => {}); }); } diff --git a/src/utils/DockerUtil.js b/src/utils/DockerUtil.js index 9a7e14c0..0ec52f08 100644 --- a/src/utils/DockerUtil.js +++ b/src/utils/DockerUtil.js @@ -73,6 +73,8 @@ export default { if (containerData.NetworkSettings && containerData.NetworkSettings.Ports) { startopts.PortBindings = containerData.NetworkSettings.Ports; + } else if (containerData.HostConfig && containerData.HostConfig.PortBindings) { + startopts.PortBindings = containerData.HostConfig.PortBindings; } else { startopts.PublishAllPorts = true; } From d0b674919377d56c4e858f6a7fc9312ef64e1144 Mon Sep 17 00:00:00 2001 From: TeckniX Date: Wed, 27 May 2015 14:13:03 -0400 Subject: [PATCH 18/27] Removed old comment for dockerUtil restart Signed-off-by: TeckniX --- src/components/ContainerDetailsSubheader.react.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ContainerDetailsSubheader.react.js b/src/components/ContainerDetailsSubheader.react.js index 8ab70738..f5ee477c 100644 --- a/src/components/ContainerDetailsSubheader.react.js +++ b/src/components/ContainerDetailsSubheader.react.js @@ -83,7 +83,6 @@ var ContainerDetailsSubheader = React.createClass({ handleRestart: function () { if (!this.disableRestart()) { metrics.track('Restarted Container'); - //dockerUtil.restart(this.props.container.Name); containerActions.restart(this.props.container.Name); } }, From 9a6b0821212fd79c593d2a8c8fa49f2c02b101f8 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Wed, 27 May 2015 12:45:41 -0700 Subject: [PATCH 19/27] Fixed tab label hover. --- styles/new-container.less | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/styles/new-container.less b/styles/new-container.less index eddda2c4..66884d19 100644 --- a/styles/new-container.less +++ b/styles/new-container.less @@ -50,16 +50,18 @@ flex-direction: row; justify-content: flex-end; font-size: 13px; - margin: 0 20px; + margin: 0 10px; margin-bottom: 10px; .results-filter { text-align: center; margin: 0 10px; min-width: 40px; - &:hover { - border-radius: 40px; - background-color: @gray-lightest; + &.tab { + &:hover { + border-radius: 40px; + background-color: @gray-lightest; + } } } From a5f73e1e64cce9661f8fd300708b975259030dc6 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Wed, 27 May 2015 14:07:49 -0700 Subject: [PATCH 20/27] Added informative text for selecting image tags. --- src/components/ImageCard.react.js | 1 + styles/new-container.less | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/components/ImageCard.react.js b/src/components/ImageCard.react.js index 8f9be4bb..86efd89c 100644 --- a/src/components/ImageCard.react.js +++ b/src/components/ImageCard.react.js @@ -144,6 +144,7 @@ var ImageCard = React.createClass({ return (
+

Please select an image tag.

{tags}
diff --git a/styles/new-container.less b/styles/new-container.less index 66884d19..0a7611b1 100644 --- a/styles/new-container.less +++ b/styles/new-container.less @@ -194,6 +194,11 @@ font-size: 13px; display: none; padding: 10px; + p { + color: white; + padding-bottom: 7px; + border-bottom: 1px solid rgba(255,255,255,0.2); + } .tag-list { display: flex; flex-direction: row; From b1449426e76baed4b3c68ed56a05be00e75cfd05 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Wed, 27 May 2015 14:09:03 -0700 Subject: [PATCH 21/27] Fixed scrolling. --- styles/new-container.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/new-container.less b/styles/new-container.less index 0a7611b1..141228b8 100644 --- a/styles/new-container.less +++ b/styles/new-container.less @@ -205,7 +205,7 @@ align-items: flex-start; align-content: flex-start; flex-flow: row wrap; - height: 140px; + height: 100px; overflow: auto; .tag { display: inline-block; From 903a36904a37b8a8bc2e2a30d91c977c7e05b59a Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Wed, 27 May 2015 14:20:44 -0700 Subject: [PATCH 22/27] Integration tests --- .circle.yml | 3 ++ .gitignore | 3 ++ __integration__/HubUtil-integration.js | 39 +++++++++------ __integration__/RegHubUtil-integration.js | 58 +++++++++++++++++++++-- src/actions/RepositoryServerActions.js | 3 +- src/actions/TagServerActions.js | 3 +- src/stores/TagStore.js | 5 ++ src/utils/HubUtil.js | 13 +++-- src/utils/RegHubUtil.js | 42 +++++++++++----- util/testenv.js | 2 +- 10 files changed, 136 insertions(+), 35 deletions(-) create mode 100644 .circle.yml diff --git a/.circle.yml b/.circle.yml new file mode 100644 index 00000000..5ab4115a --- /dev/null +++ b/.circle.yml @@ -0,0 +1,3 @@ +test: + override: + - npm run integration diff --git a/.gitignore b/.gitignore index 5f98bcf3..3b0964fe 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ npm-debug.log # Signing Identity identity* +# Integration test environment +integration + # Resources resources/docker-* resources/boot2docker-* diff --git a/__integration__/HubUtil-integration.js b/__integration__/HubUtil-integration.js index d6638c35..cdde6a0c 100644 --- a/__integration__/HubUtil-integration.js +++ b/__integration__/HubUtil-integration.js @@ -1,23 +1,32 @@ jest.autoMockOff(); +let hubUtil = require('../src/utils/HubUtil'); +let Promise = require('bluebird'); + +jasmine.getEnv().DEFAULT_TIMEOUT_INTERVAL = 60000; + describe('HubUtil Integration Tests', () => { - describe('token refresh', () => { - it('re-auths if the token has expired', () => { - expect(true).toBe(true); + describe('auth', () => { + pit('successfully authenticates', () => { + return new Promise((resolve) => { + hubUtil.auth(process.env.INTEGRATION_USER, process.env.INTEGRATION_PASSWORD, (error, response, body) => { + expect(response.statusCode).toBe(200); + expect(error).toBe(null); + + let data = JSON.parse(body); + expect(data.token).toBeTruthy(); + resolve(); + }); + }); }); - }); - - describe('signup', () => { - it('returns a 204 and sets localstorage data', () => { - }); - }); - - describe('login', () => { - it('Returns a 401 with account not active string if not active', () => { - - }); - it('Returns a 401 if the password is wrong', () => { + pit('provides a 401 if credentials are incorrect', () => { + return new Promise((resolve) => { + hubUtil.auth(process.env.INTEGRATION_USER, 'incorrectpassword', (error, response) => { + expect(response.statusCode).toBe(401); + resolve(); + }); + }); }); }); }); diff --git a/__integration__/RegHubUtil-integration.js b/__integration__/RegHubUtil-integration.js index 782a4990..1f7b0f4f 100644 --- a/__integration__/RegHubUtil-integration.js +++ b/__integration__/RegHubUtil-integration.js @@ -1,9 +1,61 @@ jest.autoMockOff(); -describe('RegHubUtil Integration Tests', () => { - describe('repos', () => { - it('returns set of repos', () => { +// One minute timeout for integration tests +jasmine.getEnv().DEFAULT_TIMEOUT_INTERVAL = 60000; +let _ = require('underscore'); +let regHubUtil = require('../src/utils/RegHubUtil'); +let hubUtil = require('../src/utils/hubUtil'); +let Promise = require('bluebird'); + +describe('RegHubUtil Integration Tests', () => { + describe('with login', () => { + pit('lists private repos', () => { + return new Promise((resolve) => { + hubUtil.login(process.env.INTEGRATION_USER, process.env.INTEGRATION_PASSWORD, () => { + regHubUtil.repos((error, repos) => { + expect(_.findWhere(repos, {name: 'test_private', is_private: true})).toBeTruthy(); + resolve(); + }); + }); + }); + }); + + pit('lists tags for a private repo', () => { + return new Promise((resolve) => { + hubUtil.login(process.env.INTEGRATION_USER, process.env.INTEGRATION_PASSWORD, () => { + regHubUtil.tags(`${process.env.INTEGRATION_USER}/test_private`, (error, tags) => { + expect(error).toBeFalsy(); + expect(tags).toEqual(['latest']); + resolve(); + }); + }); + }); + }); + }); + + describe('public repos', () => { + pit('lists repos', () => { + return new Promise((resolve) => { + hubUtil.login(process.env.INTEGRATION_USER, process.env.INTEGRATION_PASSWORD, () => { + regHubUtil.repos((error, repos) => { + expect(_.findWhere(repos, {name: 'test'})).toBeTruthy(); + resolve(); + }); + }); + }); + }); + + pit('lists tags for a repo', () => { + return new Promise((resolve) => { + hubUtil.login(process.env.INTEGRATION_USER, process.env.INTEGRATION_PASSWORD, () => { + regHubUtil.tags(`${process.env.INTEGRATION_USER}/test`, (error, tags) => { + expect(error).toBeFalsy(); + expect(tags).toEqual(['latest']); + resolve(); + }); + }); + }); }); }); }); diff --git a/src/actions/RepositoryServerActions.js b/src/actions/RepositoryServerActions.js index b49e4d60..9b4740ff 100644 --- a/src/actions/RepositoryServerActions.js +++ b/src/actions/RepositoryServerActions.js @@ -6,7 +6,8 @@ class RepositoryServerActions { 'reposLoading', 'resultsUpdated', 'recommendedUpdated', - 'reposUpdated' + 'reposUpdated', + 'error' ); } } diff --git a/src/actions/TagServerActions.js b/src/actions/TagServerActions.js index 4149b81c..d8356b6c 100644 --- a/src/actions/TagServerActions.js +++ b/src/actions/TagServerActions.js @@ -3,7 +3,8 @@ import alt from '../alt'; class TagServerActions { constructor () { this.generateActions( - 'tagsUpdated' + 'tagsUpdated', + 'error' ); } } diff --git a/src/stores/TagStore.js b/src/stores/TagStore.js index 9293bb16..13a2b980 100644 --- a/src/stores/TagStore.js +++ b/src/stores/TagStore.js @@ -38,6 +38,11 @@ class TagStore { this.tags = {}; this.emitChange(); } + + error ({repo}) { + this.loading[repo] = false; + this.emitChange(); + } } export default alt.createStore(TagStore); diff --git a/src/utils/HubUtil.js b/src/utils/HubUtil.js index a4db7131..02ce497a 100644 --- a/src/utils/HubUtil.js +++ b/src/utils/HubUtil.js @@ -2,6 +2,8 @@ var _ = require('underscore'); var request = require('request'); var accountServerActions = require('../actions/AccountServerActions'); +let HUB2_ENDPOINT = process.env.HUB2_ENDPOINT || 'https://hub.docker.com/v2'; + module.exports = { init: function () { accountServerActions.prompted({prompted: localStorage.getItem('auth.prompted')}); @@ -95,10 +97,11 @@ module.exports = { localStorage.removeItem('auth.config'); }, - login: function (username, password) { + login: function (username, password, callback) { this.auth(username, password, (error, response, body) => { if (error) { accountServerActions.errors({errors: {detail: error.message}}); + callback(error); return; } @@ -112,9 +115,11 @@ module.exports = { localStorage.setItem('auth.config', new Buffer(username + ':' + password).toString('base64')); accountServerActions.loggedin({username, verified: true}); accountServerActions.prompted({prompted: true}); + if (callback) { callback(); } require('./RegHubUtil').repos(); } else { accountServerActions.errors({errors: {detail: 'Did not receive login token.'}}); + if (callback) { callback(new Error('Did not receive login token.')); } } } else if (response.statusCode === 401) { if (data && data.detail && data.detail.indexOf('Account not active yet') !== -1) { @@ -123,15 +128,17 @@ module.exports = { localStorage.setItem('auth.username', username); localStorage.setItem('auth.verified', false); localStorage.setItem('auth.config', new Buffer(username + ':' + password).toString('base64')); + if (callback) { callback(); } } else { accountServerActions.errors({errors: data}); + if (callback) { callback(new Error(data.detail)); } } } }); }, auth: function (username, password, callback) { - request.post('https://hub.docker.com/v2/users/login/', {form: {username, password}}, (error, response, body) => { + request.post(`${HUB2_ENDPOINT}/users/login/`, {form: {username, password}}, (error, response, body) => { callback(error, response, body); }); }, @@ -153,7 +160,7 @@ module.exports = { // Signs up and places a token under ~/.dockercfg and saves a jwt to localstore signup: function (username, password, email, subscribe) { - request.post('https://hub.docker.com/v2/users/signup/', { + request.post('${HUB2_ENDPOINT}/users/signup/', { form: { username, password, diff --git a/src/utils/RegHubUtil.js b/src/utils/RegHubUtil.js index 3975ce96..25e9b3e6 100644 --- a/src/utils/RegHubUtil.js +++ b/src/utils/RegHubUtil.js @@ -5,7 +5,9 @@ var util = require('../utils/Util'); var hubUtil = require('../utils/HubUtil'); var repositoryServerActions = require('../actions/RepositoryServerActions'); var tagServerActions = require('../actions/TagServerActions'); +var Promise = require('bluebird'); +let REGHUB2_ENDPOINT = process.env.REGHUB2_ENDPOINT || 'https://registry.hub.docker.com/v2'; let searchReq = null; module.exports = { @@ -38,7 +40,7 @@ module.exports = { qs: {q: query, page} }, (error, response, body) => { if (error) { - repositoryServerActions.searchError({error}); + repositoryServerActions.error({error}); } let data = JSON.parse(body); @@ -66,7 +68,7 @@ module.exports = { } request.get({ - url: `https://registry.hub.docker.com/v2/repositories/${name}`, + url: `${REGHUB2_ENDPOINT}/repositories/${name}`, }, (error, response, body) => { if (error) { repositoryServerActions.error({error}); @@ -86,28 +88,38 @@ module.exports = { }); }, - tags: function (repo) { + tags: function (repo, callback) { hubUtil.request({ - url: `https://registry.hub.docker.com/v2/repositories/${repo}/tags` + url: `${REGHUB2_ENDPOINT}/repositories/${repo}/tags` }, (error, response, body) => { if (response.statusCode === 200) { let data = JSON.parse(body); tagServerActions.tagsUpdated({repo, tags: data.tags}); - } else if (response.statusCude === 401) { - return; + if (callback) { callback(null, data.tags); } + } else if (error || response.statusCode === 401) { + repositoryServerActions.error({repo}); + if (callback) { callback(new Error('Failed to fetch repos')); } } }); }, // Returns the base64 encoded index token or null if no token exists - repos: function () { + repos: function (callback) { repositoryServerActions.reposLoading({repos: []}); hubUtil.request({ - url: 'https://registry.hub.docker.com/v2/namespaces/', + url: `${REGHUB2_ENDPOINT}/namespaces/`, }, (error, response, body) => { if (error) { - repositoryServerActions.reposError({error}); + repositoryServerActions.error({error}); + if (callback) { callback(error); } + return; + } + + if (response.statusCode !== 200) { + let generalError = new Error('Failed to fetch repos'); + repositoryServerActions.error({error: generalError}); + if (callback) { callback({error: generalError}); } return; } @@ -115,10 +127,11 @@ module.exports = { let namespaces = data.namespaces; async.map(namespaces, (namespace, cb) => { hubUtil.request({ - url: `https://registry.hub.docker.com/v2/repositories/${namespace}` + url: `${REGHUB2_ENDPOINT}/repositories/${namespace}` }, (error, response, body) => { if (error) { - repositoryServerActions.reposError({error}); + repositoryServerActions.error({error}); + if (callback) { callback(error); } return; } @@ -126,6 +139,12 @@ module.exports = { cb(null, data.results); }); }, (error, lists) => { + if (error) { + repositoryServerActions.error({error}); + if (callback) { callback(error); } + return; + } + let repos = []; for (let list of lists) { repos = repos.concat(list); @@ -136,6 +155,7 @@ module.exports = { }); repositoryServerActions.reposUpdated({repos}); + if (callback) { callback(null, repos); } }); }); } diff --git a/util/testenv.js b/util/testenv.js index 55db09ad..d2a95c4a 100644 --- a/util/testenv.js +++ b/util/testenv.js @@ -1,6 +1,6 @@ var mock = (function() { var store = {}; - return { + return { getItem: function(key) { return store[key]; }, From 60a9cae45179cd65a5a1e20f823d2dd4de77ae45 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Wed, 27 May 2015 14:26:20 -0700 Subject: [PATCH 23/27] Removing circle.yml --- .circle.yml | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .circle.yml diff --git a/.circle.yml b/.circle.yml deleted file mode 100644 index 5ab4115a..00000000 --- a/.circle.yml +++ /dev/null @@ -1,3 +0,0 @@ -test: - override: - - npm run integration From a5d674aa4ff8c4887212ddab7e93579209a7236c Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Wed, 27 May 2015 14:31:19 -0700 Subject: [PATCH 24/27] Fix lowercase typo --- __integration__/RegHubUtil-integration.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/__integration__/RegHubUtil-integration.js b/__integration__/RegHubUtil-integration.js index 1f7b0f4f..5b674b89 100644 --- a/__integration__/RegHubUtil-integration.js +++ b/__integration__/RegHubUtil-integration.js @@ -1,11 +1,10 @@ -jest.autoMockOff(); // One minute timeout for integration tests jasmine.getEnv().DEFAULT_TIMEOUT_INTERVAL = 60000; let _ = require('underscore'); let regHubUtil = require('../src/utils/RegHubUtil'); -let hubUtil = require('../src/utils/hubUtil'); +let hubUtil = require('../src/utils/HubUtil'); let Promise = require('bluebird'); describe('RegHubUtil Integration Tests', () => { From a3aec13850e264fd826819594b534365e3b9c1c9 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Wed, 27 May 2015 14:37:22 -0700 Subject: [PATCH 25/27] Removing whitespace --- __integration__/RegHubUtil-integration.js | 1 - 1 file changed, 1 deletion(-) diff --git a/__integration__/RegHubUtil-integration.js b/__integration__/RegHubUtil-integration.js index 5b674b89..19eb765a 100644 --- a/__integration__/RegHubUtil-integration.js +++ b/__integration__/RegHubUtil-integration.js @@ -1,4 +1,3 @@ - // One minute timeout for integration tests jasmine.getEnv().DEFAULT_TIMEOUT_INTERVAL = 60000; From c8067c92c025ce4adbdfa163be6dd8337d28ce3d Mon Sep 17 00:00:00 2001 From: Sean Li Date: Wed, 27 May 2015 14:40:23 -0700 Subject: [PATCH 26/27] Tweaked web preview height. --- styles/container-home.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/container-home.less b/styles/container-home.less index 66232d04..e13bc062 100644 --- a/styles/container-home.less +++ b/styles/container-home.less @@ -30,7 +30,7 @@ .widget-style(); background-color: white; width: 100%; - height: 100%; + height: 95%; p { font-size: 13px; color: @gray-normal; From 92242b7d91825d1a8c3f0884219db2328fa312ee Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Wed, 27 May 2015 14:49:29 -0700 Subject: [PATCH 27/27] Adding back automock in integration test --- __integration__/RegHubUtil-integration.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__integration__/RegHubUtil-integration.js b/__integration__/RegHubUtil-integration.js index 19eb765a..ee49ddd9 100644 --- a/__integration__/RegHubUtil-integration.js +++ b/__integration__/RegHubUtil-integration.js @@ -1,3 +1,5 @@ +jest.autoMockOff(); + // One minute timeout for integration tests jasmine.getEnv().DEFAULT_TIMEOUT_INTERVAL = 60000;