coupled to global variables In Ruby constants are global and can be overwritten c l a s s F o o # . . . e n d F o o = C l a s s . n e w d o # . . . e n d $ f o o _ c l a s s = C l a s s . n e w d o # . . . e n d
fruit Every month The fruit changes We're looking to raise $1.000.000 at a $10.000.000 valuation We're also hiring senior Rails engineers with 3+ months experience
a f r u i t e n t h u s i a s t A n d I l i v e f o r t o d a y b e c a u s e t o m o r r o w m a y n e v e r c o m e W h e n I v i s i t t h e i n s e a s o n n o w p a g e T h e n I s e e a l i s t o f f r u i t s t h a t a r e a v a i l a b l e t o d a y
s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r d e f i n _ s e a s o n r e n d e r ( j s o n : F r u i t . i n _ s e a s o n ) e n d e n d
< A c t i v e R e c o r d : : B a s e d e f s e l f . i n _ s e a s o n a l l . w h e r e ( " s e a s o n _ s t a r t > = ? " , D a t e . t o d a y ) . w h e r e ( " s e a s o n _ e n d < = ? " , D a t e . t o d a y ) e n d e n d
r i b e F r u i t d o d e s c r i b e " . i n _ s e a s o n " d o b e f o r e { s e e d _ f r u i t s } c o n t e x t " i n s u m m e r " d o b e f o r e { T i m e c o p . t r a v e l ( D a t e . n e w ( 2 0 1 6 , 7 , 1 ) ) } i t " r e t u r n s s u m m e r f r u i t s " d o e x p e c t ( F r u i t . i n _ s e a s o n ) . t o i n c l u d e ( * s u m m e r _ f r u i t s ) e n d i t " e x c l u d e s w i n t e r f r u i t s " d o e x p e c t ( F r u i t . i n _ s e a s o n ) . n o t _ t o i n c l u d e ( * w i n t e r _ f r u i t s ) e n d e n d c o n t e x t " i n w i n t e r " d o # . . . e n d e n d e n d
d e s c r i b e F r u i t d o d e s c r i b e " . i n _ s e a s o n " d o b e f o r e { s e e d _ f r u i t s } c o n t e x t " i n s u m m e r " d o l e t ( : d a t e ) { D a t e . n e w ( 2 0 1 6 , 7 , 1 ) } i t " r e t u r n s s u m m e r f r u i t s " d o e x p e c t ( F r u i t . i n _ s e a s o n ( d a t e ) ) . t o i n c l u d e ( * s u m m e r _ f r u i t s ) e n d i t " e x c l u d e s w i n t e r f r u i t s " d o e x p e c t ( F r u i t . i n _ s e a s o n ( d a t e ) ) . n o t _ t o i n c l u d e ( * w i n t e r _ f r u i t s ) e n d e n d c o n t e x t " i n w i n t e r " d o # . . . e n d e n d e n d
< A c t i v e R e c o r d : : B a s e d e f s e l f . i n _ s e a s o n ( d a t e ) a l l . w h e r e ( " s e a s o n _ s t a r t > = ? " , d a t e ) . w h e r e ( " s e a s o n _ e n d < = ? " , d a t e ) e n d e n d
s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r d e f i n _ s e a s o n r e n d e r ( j s o n : F r u i t . i n _ s e a s o n ( d a t e ) ) e n d p r i v a t e d e f d a t e p a r a m s . f e t c h ( " d a t e " , D a t e . t o d a y ) e n d e n d
a f r u i t e n t h u s i a s t A n d I l i k e t o d r e a m a b o u t t h e f u t u r e W h e n I v i s i t t h e i n s e a s o n p a g e f o r J a n u a r y T h e n I s e e t h e f r u i t s t h a t w i l l a v a i l a b l e i n J a n u a r y
a f r u i t e n t h u s i a s t A n d I h a v e a g o o g l e a c c o u n t W h e n I s i g n i n T h e n I c a n a u t h e n t i c a t e w i t h G o o g l e r a t h e r t h a n u s e a p a s s w o r d
c l a s s U s e r S e s s i o n s C o n t r o l l e r d e f c r e a t e s i g n _ i n ( u s e r ) r e d i r e c t _ t o ( h o m e _ p a t h ) e n d p r i v a t e d e f u s e r # . . . e n d e n d How exactly do we get the authenticated user?
c l a s s U s e r S e s s i o n s C o n t r o l l e r # . . . d e f u s e r U s e r . f i n d _ b y _ e m a i l ( e m a i l ) e n d d e f e m a i l u s e r _ i n f o . f e t c h ( " e m a i l " ) e n d d e f u s e r _ i n f o # . . . e n d e n d
l a s s U s e r S e s s i o n s C o n t r o l l e r # . . . d e f u s e r _ i n f o a u t h _ c l i e n t . c o d e = p a r a m s . f e t c h ( " c o d e " ) a u t h _ c l i e n t . f e t c h _ a c c e s s _ t o k e n ! a u t h _ c l i e n t . d e c o d e _ j w t e n d d e f a u t h _ c l i e n t @ a u t h _ c l i e n t | | = S i g n e t : : O A u t h 2 : : C l i e n t . n e w ( s c o p e : " e m a i l p r o f i l e " , c l i e n t _ i d : R a i l s . a p p l i c a t i o n . s e c r e t s . g o o g l e _ c l i e n t _ i d , c l i e n t _ s e c r e t : R a i l s . a p p l i c a t i o n . s e c r e t s . g o o g l e _ c l i e n t _ s e c r e t , a u t h o r i z a t i o n _ u r i : " h t t p s : / / a c c o u n t s . g o o g l e . c o m / o / o a u t h 2 / a u t h " t o k e n _ c r e d e n t i a l _ u r i : " h t t p s : / / w w w . g o o g l e a p i s . c o m / o a u t h 2 / v 3 / t o k e n " r e d i r e c t _ u r i : " h t t p : / / e x a m p l e . c o m / u s e r _ s e s s i o n s / c r e a t e " ) e n d e n d
/ i d _ t o k e n h e r e i s t h e J S O N w e b t o k e n c o n t a i n i n g t h e u s e r ' s d e t a i l s { " a c c e s s _ t o k e n " : " y a 2 9 . C i 8 O A 1 n 0 b x I 5 h l K D U U C z 2 f J J Z m 9 H w c u K r q c k Y 5 S E C X T O 5 H x V i 0 6 " t o k e n _ t y p e " : " B e a r e r " , " e x p i r e s _ i n " : 3 6 0 0 , " r e f r e s h _ t o k e n " : " 1 / T - O z b 2 5 L 3 4 Z C r M S k r 1 v M 1 q H M O 2 T - 0 B t m M e X o x q 5 K E M 0 " , " i d _ t o k e n " : " e y J h b G c i O i J S U z I 1 N i I s I m t p Z C I 6 I m V k Z D F j Z m F j N T E y O D c z Z j U z Y j A 2 M G Q y }
# T e s t h e l p e r d e f s t u b _ a c c e s s _ t o k e n ( a u t h c o d e ) s t u b _ r e q u e s t ( : p o s t , " h t t p s : / / w w w . g o o g l e a p i s . c o m / o a u t h 2 / v 3 / t o k e n " ) . w i t h ( b o d y : { " c o d e " = > a u t h c o d e , " g r a n t _ t y p e " = > " a u t h o r i z a t i o n _ c o d e " , " r e d i r e c t _ u r i " = > " h t t p : / / e x a m p l e . c o m / u s e r _ s e s s i o n s / c r e a t e " " c l i e n t _ i d " = > R a i l s . a p p l i c a t i o n . s e c r e t s . g o o g l e _ c l i e n t _ i d , " c l i e n t _ s e c r e t " = > R a i l s . a p p l i c a t i o n . s e c r e t s . g o o g l e _ c l i e n t _ s e c r e t } ) . t o _ r e t u r n ( b o d y : J S O N . d u m p ( g o o g l e _ a c c e s s _ t o k e n _ f i x t u r e ) , h e a d e r s : { " C o n t e n t - T y p e " = > " a p p l i c a t i o n / j s o n " } ) e n d
a t u r e h a s e x p i r e d ( J W T : : E x p i r e d S i g n a t u r e ) . / a p p / c o n t r o l l e r s / u s e r _ s e s s i o n s _ c o n t r o l l e r . r b : 3 5 : i n ` u s e r _ i n f o ' . / a p p / c o n t r o l l e r s / u s e r _ s e s s i o n s _ c o n t r o l l e r . r b : 5 : i n ` c r e a t e ' . / f e a t u r e s / s u p p o r t / f e a t u r e _ a p p l i c a t i o n _ a c t i o n s . r b : 3 : i n ` s i m u l a t e _ g o o g l e _ a u t . / f e a t u r e s / s t e p _ d e f i n i t i o n s / a u t h e n t i c a t i o n _ s t e p s . r b : 1 6 : i n ` / ^ I s i g n i n $ / ' f e a t u r e s / a u t h e n t i c a t i o n . f e a t u r e : 5 : i n ` W h e n I s i g n i n '
time for every test Remove the time constraint (opening us to replay attacks) Furthermore, to sign in a different user we need another opauque awkward fixture!
l a s s S i g n e t A d a p t e r d e f i n i t i a l i z e ( c l i e n t _ i d : , c l i e n t _ s e c r e t : , r e d i r e c t _ u r i : ) @ c l i e n t _ i d = c l i e n t _ i d @ c l i e n t _ s e c r e t = c l i e n t _ s e c r e t @ r e d i r e c t _ u r i = r e d i r e c t _ u r i e n d d e f a u t h e n t i c a t e ( c o d e ) c l i e n t . c o d e = c o d e c l i e n t . f e t c h _ a c c e s s _ t o k e n ! c l i e n t . d e c o d e d _ i d _ t o k e n e n d p r i v a t e d e f c l i e n t @ c l i e n t | | = S i g n e t : : O A u t h 2 : : C l i e n t . n e w ( # . . . ) e n d # . . . e n d
l a s s A u t h e n t i c a t e U s e r d e f i n i t i a l i z e ( a u t h _ c l i e n t , u s e r s , c o d e ) @ a u t h _ c l i e n t = a u t h _ c l i e n t @ u s e r s = u s e r s @ c o d e = c o d e e n d d e f c a l l u s e r s . f i n d _ b y _ e m a i l ( e m a i l ) e n d p r i v a t e d e f e m a i l u s e r _ i n f o . f e t c h ( " e m a i l " ) e n d d e f u s e r _ i n f o a u t h _ c l i e n t . a u t h e n t i c a t e ( c o d e ) e n d e n d
from somewhere The controller still has lots of knowledge c l a s s U s e r S e s s i o n s C o n t r o l l e r d e f c r e a t e s i g n _ i n ( u s e r ) r e d i r e c t _ t o ( h o m e _ p a t h ) e n d p r i v a t e d e f u s e r A u t h e n t i c a t e U s e r . n e w ( a u t h _ c l i e n t , U s e r , p a r a m s . f e t c h ( " c o d e " ) ) e n d e n d
s U s e r S e s s i o n s C o n t r o l l e r d e f c r e a t e s i g n _ i n ( u s e r ) r e d i r e c t _ t o ( h o m e _ p a t h ) e n d p r i v a t e d e f u s e r a p p . a u t h e n t i c a t e _ u s e r ( p a r a m s . f e t c h ( " c o d e " ) ) e n d e n d
a s s F r u i t O f T h e M o n t h A p p d e f i n i t i a l i z e ( a u t h _ c l i e n t : . . . ) # I n j e c t a l l e x t e r n a l d e p e n d e n c i e s h e r e . . . e n d d e f a u t h e n t i c a t e _ u s e r ( c o d e ) A u t h e n t i c a t e U s e r . n e w ( a u t h _ c l i e n t , U s e r , c o d e ) . c a l l e n d e n d
need for env checks - a pernicious source of ifs # c o n f i g / e n v i r o n m e n t s / t e s t . r b A P P = F r u i t O f T h e M o n t h A p p . n e w ( a u t h _ c l i e n t : M O C K _ A U T H _ C L I E N T ) c l a s s A p p l i c a t i o n C o n t r o l l e r p r i v a t e d e f a p p A P P e n d e n d
s s M o c k G o o g l e A u t h e n t i c a t i o n d e f i n i t i a l i z e ( u s e r _ i n f o ) @ u s e r _ i n f o = u s e r _ i n f o e n d d e f a u t h e n t i c a t e ( _ c o d e ) @ u s e r _ i n f o e n d e n d M O C K _ A U T H _ C L I E N T = M o c k G o o g l e A u t h e n t i c a t i o n . n e w ( " e m a i l " = > " b e s t i e @ g m a i l . c o