From 5d8da5052a689d9417cd020c2e46f2ddadbd468e Mon Sep 17 00:00:00 2001 From: Paul Kaplan <pkaplan@media.mit.edu> Date: Wed, 2 Aug 2017 11:44:45 -0400 Subject: [PATCH] Add effect buttons and tests for the component --- src/components/icon-button/icon-button.css | 2 +- src/components/sound-editor/icon--echo.svg | Bin 0 -> 1515 bytes src/components/sound-editor/icon--higher.svg | Bin 0 -> 2897 bytes src/components/sound-editor/icon--louder.svg | Bin 0 -> 1272 bytes src/components/sound-editor/icon--lower.svg | Bin 0 -> 2911 bytes src/components/sound-editor/icon--reverse.svg | Bin 0 -> 4349 bytes src/components/sound-editor/icon--robot.svg | Bin 0 -> 1295 bytes src/components/sound-editor/icon--softer.svg | Bin 0 -> 1280 bytes src/components/sound-editor/sound-editor.css | 14 +++ src/components/sound-editor/sound-editor.jsx | 95 ++++++++++++++ src/containers/sound-editor.jsx | 16 ++- .../__snapshots__/sound-editor.test.jsx.snap | 116 ++++++++++++++++++ test/unit/components/sound-editor.test.jsx | 31 +++++ test/unit/containers/sound-editor.test.jsx | 2 +- 14 files changed, 273 insertions(+), 3 deletions(-) create mode 100644 src/components/sound-editor/icon--echo.svg create mode 100644 src/components/sound-editor/icon--higher.svg create mode 100644 src/components/sound-editor/icon--louder.svg create mode 100644 src/components/sound-editor/icon--lower.svg create mode 100644 src/components/sound-editor/icon--reverse.svg create mode 100644 src/components/sound-editor/icon--robot.svg create mode 100644 src/components/sound-editor/icon--softer.svg diff --git a/src/components/icon-button/icon-button.css b/src/components/icon-button/icon-button.css index 112fabad2..ebd7fd656 100644 --- a/src/components/icon-button/icon-button.css +++ b/src/components/icon-button/icon-button.css @@ -8,6 +8,7 @@ transition: 0.2s; font-size: 0.75rem; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + color: $motion-primary; } .container:hover { @@ -20,5 +21,4 @@ .title { margin-top: 0.5rem; - color: $motion-primary; } diff --git a/src/components/sound-editor/icon--echo.svg b/src/components/sound-editor/icon--echo.svg new file mode 100644 index 0000000000000000000000000000000000000000..de8b28a5e53fdb2f6995608509997a518e465514 GIT binary patch literal 1515 zcmcC1E=yOa$j!+swpGd~DJihh*Do(G*DE*H%P&gTH!?6V&@V1aSAr<9s>sRA%f_bA z(9+UUA1te+P?lO$oSC0zt7NEWsH9L~t7K46p`=g=rOPr?%boHoY?Vw56hO$#NWsL+ zNJ*i%q%tSfRw*?vF)1fiHz_eWJH05sG%v*}FST63K*2!4)X)fot-)@wDlSM&PPJ7k zC`v6(Eh<Y@va?CIvnfa{$xukk%*nA;Qg(JTGj?`UQb@5?@-?zB)U(tvwlvl=O4c>h zGu1KBHP$oKHPAEDHPJKDHPo|6)-}>IhGR25LmdNM3q8|hV`Du_T@ayTYNThTYi<dl z4UNq843iCXO)T^bbqy`_%ymI#>w?vQ<rEYYa2W};NXJai5M-f_1;{<g#%6j(I$**S zWV?llp0N&?WoT@wXI89hXsKtZV`-^pqKgn!P*89-vM>RA%}CEo$H>B1&jjL49V9PT zDe2qU=%?ckAyZR5V;y5NGd*(>L&(TX&q5bO=$IJlndzDt>6t=Uh6V<DX2}M+#umDU zCVCdS=Ei#Fx?nY68InWD$WqTx2TYil>KW>ond@2TfLVqHmc_b;W;zxIx-h=8k*NhJ zD9k`%X=G{!3L=o-bc_)GR8UYLDrAf-^el9YO$_u5Nemei13e2}5TOGibPWy6^^9~3 zbPY{#r8ZEIU{4(;rl3%T6NZMCphTl%XlCkcWDHK*#vl<RV*^kug50WOgm5=e-ZU@* zX*D#~Gb7QPMrL|Opafu~17?|lg3CbH(iBJf$L&dD15h-<2@69|F4QqJG;%gF0H;nv zV;v&{V^C~>oT+1ka56DIG&DEWGuJV)0OefL3IS6+GhI_XGaXPqH#7!QMxfkp4k{Z! z1%RoZi7rUe$PnZ^P_Bk!Py&P$CD>!uT+dPmgbj`KjC2ew^o(`DEF()jlVk%OLqk17 sT~JYA1j<`*8BoSIGzSH=k%gI_sg9w!xt=k^YdT2Ygog^K2)E+`0B?U$3IG5A literal 0 HcmV?d00001 diff --git a/src/components/sound-editor/icon--higher.svg b/src/components/sound-editor/icon--higher.svg new file mode 100644 index 0000000000000000000000000000000000000000..f624f7913b690cae89850600d93803f284ef5d3d GIT binary patch literal 2897 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 literal 0 HcmV?d00001 diff --git a/src/components/sound-editor/icon--louder.svg b/src/components/sound-editor/icon--louder.svg new file mode 100644 index 0000000000000000000000000000000000000000..1d3e2ef6542b3e9fa1845e7cc703fc4fe1eb9a26 GIT binary patch literal 1272 zcmcC1E=%W9P*6~)$j!+swyLmI$|xx*u+rDhE7nU)$xlkvOU}>LcdaN%%`47K%FM|u zsnj>rGtgH;(v*o^lOssGXHHIOaY<2PNq&*Op#hr4^rFOq4D6cSK~lx&R>9SlmzV36 z8|&p4rRy6R7#Qdmm!%`Ss3IpbFB_X;LrY6beXuM<d0A>vab|v=t&*XhAw;CYR>`2C zLP?<#LW8|omYG`alwV=1q-$wzs$gkks$ghp0K!TNVEN*b%A8bNrPRE{q?}aUq{QUx z^rHOIycDav)N%z~OA|{4OH)GyLjwa4wpId#wN-IJVsfgjQbAE_acWUns*;^ead~D* za)zBvT7FS#W_q4~QdVkmi9%6oVQFSjY6>(8^7D$}{z8c&9HFfM@(;u}N($wfDJ2=U zN`^`b8L64+86_a5zMW0FLZ($}MM+U&UTS`6v8_^ZYEGJx9hXhI9hXf(Vo8QVT4qj; zt&*~{o0+k*o039`t&*><g{7sQrH-YUk)C0Wu92CZiH?z>o>`8rp^2V_j-j4OvaYe7 zp^kx`v92jdPR|ldo9bDX85txS=zt`R^o(^(^~`lZ3QYAZb6{F?;KqRxrb4ojo{^5B zo&{K)fu0eF)-}>IE7LVM(ld9~wXihNGt;p&Gt{%xwXihTv(T|L1KEq@!YU<wynZn^ z)v+`;)3Z$0HPAEHHPExvHPSQGHPkcIHP$uIGtSX9)-%&F)-wXhTj)U5=zuH)xyMM) zBH2X8R0k9YhK7135Qc@Gaj~wEo{5g3v7WImSk6Mv7~&(4H97`*7P<y{W;#aTa5B;{ z(zD2c*<+w*36j?VdEG$ITnFroWK*y~W;zynrn-ivV9Llu&oEfm!pssB1Qy16rn(j| z&k*vonTd|2nVFtB$WsVULp*P(YoKQY^R_Wa1;X1#AUTk0lR=&`*E82K1cid3xt<w> zWd!!Rv7UvFk%69>E?5>MhT?aS4cPo{oNS;6vdaSQcOyNJTBBrhJquk+J!2h1BRx}H rBSTQ40I`fs^o)abElkbyj6jj7YXS2Y#Q*x~b~a!P%U+<e!j207s76Dr literal 0 HcmV?d00001 diff --git a/src/components/sound-editor/icon--lower.svg b/src/components/sound-editor/icon--lower.svg new file mode 100644 index 0000000000000000000000000000000000000000..0f73712d5fda058f1f42a50f7ca73d8ecc34e89e GIT binary patch literal 2911 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 literal 0 HcmV?d00001 diff --git a/src/components/sound-editor/icon--reverse.svg b/src/components/sound-editor/icon--reverse.svg new file mode 100644 index 0000000000000000000000000000000000000000..ae86227182527c8281fddacce6a48b6b949dcb77 GIT binary patch literal 4349 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 literal 0 HcmV?d00001 diff --git a/src/components/sound-editor/icon--robot.svg b/src/components/sound-editor/icon--robot.svg new file mode 100644 index 0000000000000000000000000000000000000000..3d6c011e8f753dabbe40c68ed2cd5b066061fc41 GIT binary patch literal 1295 zcmcC1E=yOa$j!+swpGd~DJihh*Do(G*DE*H%P&gTH!?6V&@V1aSAr<9s>sRA%f_bA z(9+UUA1te+P?lO$oSC0zt7NEWsH9L~t7K46p`=g=rOPr?%boH;q6!8Ih6Z4)q)=Q^ znUiX(l$w{Al#{BPl$e~IUX)*&mtvKdTCQM#P-zWziB)kyVsfgjQbAE_acWUns*;^e zx}8lyVo8QVT4qj;t&*~{o0+k*o039`t&*>WiJqyBseztphOSAOp|iP}o`sIFrJkjZ znVF8Uk&dY`h;NjkYgDFdp=XqAqGzmYsAH~cs%NZYrfaEZmaJ>23lcQdGuAZ+3Fw*? z>zeC;xMn(*dS(g=3dsg~<~l}t7GP|uXQ*SUXQpGSXBlP;GS}JI1Z0tsv7RZ&ViO%h zON5J(b&d5bbqsXPb&T~4b<K6m%Pf-(bU<RpdWJgYAedpKXB=i>kZho11~%42$Iu9Z zGE59Wwu6KXbPSDjP4z%>x`sw&x@LN&8Af{M$sm&qbj)?Zrs<lO=~_Bl8iK4h)-%(w zu+TFB2aOIqkg61XP0Vx*&5{jtjr5Fk4D~E@O>|6jO^QuGY#kFFlVV*%JqwVKj){VT zLNG|Rg`SZPh&HQI@HI5mGu1J()H6-iHPkcLG0-*EHPkcKHP$sQ)3r=C01JWzbc}V4 zGmP{slXVS1&epTgH2?*Wo;jE{)iW)#)HC$}8CRv?YX%Bk3yTb0L&Gq0(+qQvw?XbR z(1E)v%)$cXcym1q9f(4ReIQkEUu2j=RGEWSfr8XT&qNm-6uK5V78x){LPd2gKrlns z&>~saM9)OWK-WUYSkDZkR6#+Z%rZmQ7%l-a1*AI6%mCy|V?ARXLjyf?T_Y16BNJUC zlMIVwLy(|>j*$si21FZ~gjpC=Dfn8Lg96P=&otRU$57846k?#@(J{`@HPSN=GXqC6 zDC|IiWTa~h4kR;OQ$5oRV?Co}a6s!A>lo@8>lo`8hnbn_nN}(3<IWStmO3WpaHqrk zR16LX9Sa?cVhfOWbS!i&f=!I|Oms}lb--Gx6nu>>bxbXj!HL5_*94RnbV11j9>fX? z3W&54Y+|Tqq+@Cc(rs#q*GXoEL_5h0l+I1eb--FciNlZ-Cz%;ToMZ;l1$L5tx}6QE In6u*o03FvXT>t<8 literal 0 HcmV?d00001 diff --git a/src/components/sound-editor/icon--softer.svg b/src/components/sound-editor/icon--softer.svg new file mode 100644 index 0000000000000000000000000000000000000000..996bed23c91af44ba64f845c6c14e60e2d045f97 GIT binary patch literal 1280 zcmcC1E=%W9P*6~)$j!+swyLmI$|xx*u+rDhE7nU)$xlkvOU}>LcdaN%%`47K%FM|u zsnj>rGtgH;(v*o^lOssGXHHIOaY<2PNq&*Op#hr4^rFOq4D6cSK~lx&R>9SlmzV36 z8|&p4rRy6R7#Qdmm!%`Ss3IpbFB_X;LrY6beXuM<d0A>vab|v=t&*XhAw;CYR>`2C zLP?<#LW8|omYG`alwV=1q-$wzs$gkks$ghp0KyP0#U+(FskTa~d5K9msk%vt$=T^e z`K5U&R(YxA3c8jimI{`ph6;uT1|V#$1PW@a;)2BFR9mHjqSWHlqOw#aJDcM2%#!2` zJDarpqSVavJpZJu)Z`L{qSV6D%%ap3Xbj}%6~n!S5<@rwTLI)9h-Z`($}>|+GHjI$ zl@u~kGt)ClKumo*n{<UttJI2;qQtz^{L*4urQ+0_G$lJOn{+!an}WoW4287JoE%#v zWoI`tV`n!dg%n#QUtJ4JOFc^+OEV)q!yH{BGd&X>BSSs299=^bJqsN}J(FZzV?9G1 z13hD1Q;?jVC73qVvn(?*NH)*`NgC-H>zL}9>wpxP>RIN%wC2E#1EouaWFtKz9YZ|} zusQ=hBM_}?q-R#9Yi^`x?yPHJX`*MQV`*lnXQ^vpX|89XV`&Dm7s-WHO8R*HVs5Hq zX>O)xnXGG|XRd3YXQ^wXXQ*qaXQ*qeYoKSGqid{ZremyU1d_MVfvV8~SqO5Ek)B1e ziH@lbC=d({^-LfP3q9jvT_Zgc9YbS1V_mSEg`P3QM<8o-4D>8?4fM=(jKJY!q+_IK zkpr{GK+h5+uLJVBfu6Yz*cr*DV1vwbEc8ru4Nbw6k%^vRuû`63ijP*=)EnuF3 zcv?|cR{>8fnwjWWnwjaDgM5bYIV1!ubq(~4V173SsX+MM2qXt`ax%zg=6dEjhM=G@ zG}kkOu#CX|H`cSzF*49I(*?_d#83hNWCOMUFitkm1KDK(4*(-QkXoZ;b3F@POFd&9 zLnA#?T_ZzK$^fy9P4tX|buCQI^o&3;scQlA7bp-Ebam~xZ1mIZAQ+a<KxKv<7Xa!D BMH~PC literal 0 HcmV?d00001 diff --git a/src/components/sound-editor/sound-editor.css b/src/components/sound-editor/sound-editor.css index 1d67886da..c209d507a 100644 --- a/src/components/sound-editor/sound-editor.css +++ b/src/components/sound-editor/sound-editor.css @@ -69,3 +69,17 @@ display: flex; flex-direction: row-reverse; } + +.effect-button { + flex-basis: 150px; + color: #575e75; /* @todo discuss the multiple font colors with Carl, move to variable */ +} + +.effect-button + .effect-button { + margin: 0; +} + +.effect-button img { + width: 60px; + height: 60px; +} diff --git a/src/components/sound-editor/sound-editor.jsx b/src/components/sound-editor/sound-editor.jsx index 7ac6811ab..240e42719 100644 --- a/src/components/sound-editor/sound-editor.jsx +++ b/src/components/sound-editor/sound-editor.jsx @@ -6,14 +6,23 @@ import {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-int import Waveform from '../waveform/waveform.jsx'; import Label from '../forms/label.jsx'; import Input from '../forms/input.jsx'; + import BufferedInputHOC from '../forms/buffered-input-hoc.jsx'; import AudioTrimmer from '../../containers/audio-trimmer.jsx'; +import IconButton from '../icon-button/icon-button.jsx'; import styles from './sound-editor.css'; import playIcon from '../record-modal/icon--play.svg'; import stopIcon from '../record-modal/icon--stop-playback.svg'; import trimIcon from './icon--trim.svg'; +import echoIcon from './icon--echo.svg'; +import higherIcon from './icon--higher.svg'; +import lowerIcon from './icon--lower.svg'; +import louderIcon from './icon--louder.svg'; +import softerIcon from './icon--softer.svg'; +import robotIcon from './icon--robot.svg'; +import reverseIcon from './icon--reverse.svg'; const BufferedInput = BufferedInputHOC(Input); @@ -42,6 +51,41 @@ const messages = defineMessages({ id: 'soundEditor.save', description: 'Title of the button to save trimmed sound', defaultMessage: 'Save' + }, + faster: { + id: 'soundEditor.faster', + description: 'Title of the button to apply the faster effect', + defaultMessage: 'Faster' + }, + slower: { + id: 'soundEditor.slower', + description: 'Title of the button to apply the slower effect', + defaultMessage: 'Slower' + }, + echo: { + id: 'soundEditor.echo', + description: 'Title of the button to apply the echo effect', + defaultMessage: 'Echo' + }, + robot: { + id: 'soundEditor.robot', + description: 'Title of the button to apply the robot effect', + defaultMessage: 'Robot' + }, + louder: { + id: 'soundEditor.louder', + description: 'Title of the button to apply the louder effect', + defaultMessage: 'Louder' + }, + softer: { + id: 'soundEditor.softer', + description: 'Title of the button to apply thr.softer effect', + defaultMessage: 'Softer' + }, + reverse: { + id: 'soundEditor.reverse', + description: 'Title of the button to apply the reverse effect', + defaultMessage: 'Reverse' } }); @@ -114,6 +158,50 @@ const SoundEditor = props => ( /> </div> </div> + <div className={styles.row}> + <IconButton + className={styles.effectButton} + img={higherIcon} + title={<FormattedMessage {...messages.faster} />} + onClick={props.onFaster} + /> + <IconButton + className={styles.effectButton} + img={lowerIcon} + title={<FormattedMessage {...messages.slower} />} + onClick={props.onSlower} + /> + <IconButton + className={styles.effectButton} + img={echoIcon} + title={<FormattedMessage {...messages.echo} />} + onClick={props.onEcho} + /> + <IconButton + className={styles.effectButton} + img={robotIcon} + title={<FormattedMessage {...messages.robot} />} + onClick={props.onRobot} + /> + <IconButton + className={styles.effectButton} + img={louderIcon} + title={<FormattedMessage {...messages.louder} />} + onClick={props.onLouder} + /> + <IconButton + className={styles.effectButton} + img={softerIcon} + title={<FormattedMessage {...messages.softer} />} + onClick={props.onSofter} + /> + <IconButton + className={styles.effectButton} + img={reverseIcon} + title={<FormattedMessage {...messages.reverse} />} + onClick={props.onReverse} + /> + </div> </div> ); @@ -123,9 +211,16 @@ SoundEditor.propTypes = { name: PropTypes.string.isRequired, onActivateTrim: PropTypes.func, onChangeName: PropTypes.func.isRequired, + onEcho: PropTypes.func.isRequired, + onFaster: PropTypes.func.isRequired, + onLouder: PropTypes.func.isRequired, onPlay: PropTypes.func.isRequired, + onReverse: PropTypes.func.isRequired, + onRobot: PropTypes.func.isRequired, onSetTrimEnd: PropTypes.func, onSetTrimStart: PropTypes.func, + onSlower: PropTypes.func.isRequired, + onSofter: PropTypes.func.isRequired, onStop: PropTypes.func.isRequired, playhead: PropTypes.number, trimEnd: PropTypes.number, diff --git a/src/containers/sound-editor.jsx b/src/containers/sound-editor.jsx index d18678273..6f3bb4841 100644 --- a/src/containers/sound-editor.jsx +++ b/src/containers/sound-editor.jsx @@ -20,7 +20,8 @@ class SoundEditor extends React.Component { 'handleUpdatePlayhead', 'handleActivateTrim', 'handleUpdateTrimEnd', - 'handleUpdateTrimStart' + 'handleUpdateTrimStart', + 'handleEffect' ]); this.state = { chunkLevels: computeChunkedRMS(this.props.samples), @@ -94,6 +95,12 @@ class SoundEditor extends React.Component { handleUpdateTrimStart (trimStart) { this.setState({trimStart}); } + effectFactory (name) { + return () => this.handleEffect(name); + } + handleEffect (/* name */) { + // @todo implement effects + } render () { return ( <SoundEditorComponent @@ -104,9 +111,16 @@ class SoundEditor extends React.Component { trimStart={this.state.trimStart} onActivateTrim={this.handleActivateTrim} onChangeName={this.handleChangeName} + onEcho={this.effectFactory('echo')} + onFaster={this.effectFactory('faster')} + onLouder={this.effectFactory('louder')} onPlay={this.handlePlay} + onReverse={this.effectFactory('reverse')} + onRobot={this.effectFactory('robot')} onSetTrimEnd={this.handleUpdateTrimEnd} onSetTrimStart={this.handleUpdateTrimStart} + onSlower={this.effectFactory('slower')} + onSofter={this.effectFactory('softer')} onStop={this.handleStopPlaying} /> ); diff --git a/test/unit/components/__snapshots__/sound-editor.test.jsx.snap b/test/unit/components/__snapshots__/sound-editor.test.jsx.snap index c757bc5d5..076dd860b 100644 --- a/test/unit/components/__snapshots__/sound-editor.test.jsx.snap +++ b/test/unit/components/__snapshots__/sound-editor.test.jsx.snap @@ -309,5 +309,121 @@ exports[`Sound Editor Component matches snapshot 1`] = ` </div> </div> </div> + <div + className={undefined} + > + <div + className="" + onClick={[Function]} + > + <img + className={undefined} + src="test-file-stub" + /> + <div + className={undefined} + > + <span> + Faster + </span> + </div> + </div> + <div + className="" + onClick={[Function]} + > + <img + className={undefined} + src="test-file-stub" + /> + <div + className={undefined} + > + <span> + Slower + </span> + </div> + </div> + <div + className="" + onClick={[Function]} + > + <img + className={undefined} + src="test-file-stub" + /> + <div + className={undefined} + > + <span> + Echo + </span> + </div> + </div> + <div + className="" + onClick={[Function]} + > + <img + className={undefined} + src="test-file-stub" + /> + <div + className={undefined} + > + <span> + Robot + </span> + </div> + </div> + <div + className="" + onClick={[Function]} + > + <img + className={undefined} + src="test-file-stub" + /> + <div + className={undefined} + > + <span> + Louder + </span> + </div> + </div> + <div + className="" + onClick={[Function]} + > + <img + className={undefined} + src="test-file-stub" + /> + <div + className={undefined} + > + <span> + Softer + </span> + </div> + </div> + <div + className="" + onClick={[Function]} + > + <img + className={undefined} + src="test-file-stub" + /> + <div + className={undefined} + > + <span> + Reverse + </span> + </div> + </div> + </div> </div> `; diff --git a/test/unit/components/sound-editor.test.jsx b/test/unit/components/sound-editor.test.jsx index 9c98edda9..b3b744235 100644 --- a/test/unit/components/sound-editor.test.jsx +++ b/test/unit/components/sound-editor.test.jsx @@ -15,6 +15,13 @@ describe('Sound Editor Component', () => { onActivateTrim: jest.fn(), onChangeName: jest.fn(), onPlay: jest.fn(), + onReverse: jest.fn(), + onSofter: jest.fn(), + onLouder: jest.fn(), + onRobot: jest.fn(), + onEcho: jest.fn(), + onFaster: jest.fn(), + onSlower: jest.fn(), onSetTrimEnd: jest.fn(), onSetTrimStart: jest.fn(), onStop: jest.fn() @@ -57,4 +64,28 @@ describe('Sound Editor Component', () => { .simulate('blur'); expect(props.onChangeName).toHaveBeenCalled(); }); + test('effect buttons call the correct callbacks', () => { + const wrapper = mountWithIntl(<SoundEditor {...props} />); + + wrapper.find('[children="Reverse"]').simulate('click'); + expect(props.onReverse).toHaveBeenCalled(); + + wrapper.find('[children="Echo"]').simulate('click'); + expect(props.onEcho).toHaveBeenCalled(); + + wrapper.find('[children="Robot"]').simulate('click'); + expect(props.onRobot).toHaveBeenCalled(); + + wrapper.find('[children="Faster"]').simulate('click'); + expect(props.onFaster).toHaveBeenCalled(); + + wrapper.find('[children="Slower"]').simulate('click'); + expect(props.onSlower).toHaveBeenCalled(); + + wrapper.find('[children="Louder"]').simulate('click'); + expect(props.onLouder).toHaveBeenCalled(); + + wrapper.find('[children="Softer"]').simulate('click'); + expect(props.onSofter).toHaveBeenCalled(); + }); }); diff --git a/test/unit/containers/sound-editor.test.jsx b/test/unit/containers/sound-editor.test.jsx index 39f1e19b0..0f22da439 100644 --- a/test/unit/containers/sound-editor.test.jsx +++ b/test/unit/containers/sound-editor.test.jsx @@ -3,7 +3,7 @@ import React from 'react'; // eslint-disable-line no-unused-vars import {mountWithIntl} from '../../helpers/intl-helpers'; import configureStore from 'redux-mock-store'; import mockAudioBufferPlayer from '../../__mocks__/audio-buffer-player.js'; - +import {IntlProvider as Intl} from 'react-intl'; // eslint-disable-line no-unused-vars import SoundEditor from '../../../src/containers/sound-editor'; // eslint-disable-line no-unused-vars // eslint-disable-next-line no-unused-vars import SoundEditorComponent from '../../../src/components/sound-editor/sound-editor'; -- GitLab