rest-assured 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +17 -0
  3. data/LICENSE +22 -0
  4. data/README.markdown +78 -0
  5. data/Rakefile +4 -0
  6. data/bin/console +12 -0
  7. data/bin/rest-assured +28 -0
  8. data/cucumber.yml +3 -0
  9. data/db/migrate/20110620161740_add_fixtures.rb +12 -0
  10. data/db/migrate/20110625155332_add_redirects_table.rb +12 -0
  11. data/db/migrate/20110709150645_add_description_to_fixtures.rb +9 -0
  12. data/db/migrate/20110807222522_add_active_bit_to_fixtures.rb +9 -0
  13. data/db/migrate/20110818155555_add_position_to_redirects.rb +9 -0
  14. data/db/migrate/20110823132023_add_method_to_fixtures.rb +9 -0
  15. data/db/migrate/20110912162948_rename_url_to_fullpath.rb +9 -0
  16. data/db/migrate/20110912163705_rename_fixtures_to_doubles.rb +9 -0
  17. data/features/doubles_via_api.feature +50 -0
  18. data/features/doubles_via_ui.feature +66 -0
  19. data/features/persistence.feature +24 -0
  20. data/features/redirect_rules_via_api.feature +29 -0
  21. data/features/redirect_rules_via_ui.feature +68 -0
  22. data/features/step_definitions/doubles_steps.rb +143 -0
  23. data/features/step_definitions/persistence_steps.rb +13 -0
  24. data/features/step_definitions/redirect_rules_steps.rb +64 -0
  25. data/features/step_definitions/support/numeric_transforms.rb +3 -0
  26. data/features/support/env.rb +71 -0
  27. data/lib/rest-assured.rb +66 -0
  28. data/lib/rest-assured/config.rb +11 -0
  29. data/lib/rest-assured/init.rb +12 -0
  30. data/lib/rest-assured/models/double.rb +30 -0
  31. data/lib/rest-assured/models/redirect.rb +37 -0
  32. data/lib/rest-assured/routes/double.rb +77 -0
  33. data/lib/rest-assured/routes/redirect.rb +71 -0
  34. data/lib/rest-assured/version.rb +3 -0
  35. data/lib/sinatra/partials.rb +18 -0
  36. data/public/css/grid.inuit.css +76 -0
  37. data/public/css/inuit.css +904 -0
  38. data/public/css/jquery.jgrowl.css +132 -0
  39. data/public/css/style.css +88 -0
  40. data/public/img/css/12-grid-720.png +0 -0
  41. data/public/img/css/12-grid.png +0 -0
  42. data/public/img/css/baseline.gif +0 -0
  43. data/public/img/css/grid-720.png +0 -0
  44. data/public/img/css/grid.png +0 -0
  45. data/public/img/css/icons/error.png +0 -0
  46. data/public/img/css/icons/info.png +0 -0
  47. data/public/img/css/icons/success.png +0 -0
  48. data/public/img/css/icons/warning.png +0 -0
  49. data/public/javascript/application.js +12 -0
  50. data/public/javascript/jquery.jgrowl_minimized.js +11 -0
  51. data/rest-assured.gemspec +36 -0
  52. data/spec/functional/double_routes_spec.rb +117 -0
  53. data/spec/functional/redirect_routes_spec.rb +108 -0
  54. data/spec/models/double_spec.rb +73 -0
  55. data/spec/models/redirect_spec.rb +38 -0
  56. data/spec/spec_helper.rb +47 -0
  57. data/views/base.scss +11 -0
  58. data/views/doubles/_form.haml +16 -0
  59. data/views/doubles/edit.haml +4 -0
  60. data/views/doubles/index.haml +41 -0
  61. data/views/doubles/new.haml +3 -0
  62. data/views/layout.haml +25 -0
  63. data/views/redirects/_form.haml +11 -0
  64. data/views/redirects/edit.haml +4 -0
  65. data/views/redirects/index.haml +33 -0
  66. data/views/redirects/new.haml +3 -0
  67. metadata +250 -0
@@ -0,0 +1,132 @@
1
+
2
+ div.jGrowl {
3
+ padding: 10px;
4
+ z-index: 9999;
5
+ color: #fff;
6
+ font-size: 12px;
7
+ }
8
+
9
+ /** Special IE6 Style Positioning **/
10
+ div.ie6 {
11
+ position: absolute;
12
+ }
13
+
14
+ div.ie6.top-right {
15
+ right: auto;
16
+ bottom: auto;
17
+ left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
18
+ top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
19
+ }
20
+
21
+ div.ie6.top-left {
22
+ left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
23
+ top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
24
+ }
25
+
26
+ div.ie6.bottom-right {
27
+ left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
28
+ top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
29
+ }
30
+
31
+ div.ie6.bottom-left {
32
+ left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
33
+ top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
34
+ }
35
+
36
+ div.ie6.center {
37
+ left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
38
+ top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
39
+ width: 100%;
40
+ }
41
+
42
+ /** Normal Style Positions **/
43
+ div.jGrowl {
44
+ position: absolute;
45
+ }
46
+
47
+ body > div.jGrowl {
48
+ position: fixed;
49
+ }
50
+
51
+ div.jGrowl.top-left {
52
+ left: 0px;
53
+ top: 0px;
54
+ }
55
+
56
+ div.jGrowl.top-right {
57
+ right: 0px;
58
+ top: 0px;
59
+ }
60
+
61
+ div.jGrowl.bottom-left {
62
+ left: 0px;
63
+ bottom: 0px;
64
+ }
65
+
66
+ div.jGrowl.bottom-right {
67
+ right: 0px;
68
+ bottom: 0px;
69
+ }
70
+
71
+ div.jGrowl.center {
72
+ top: 0px;
73
+ width: 50%;
74
+ left: 25%;
75
+ }
76
+
77
+ /** Cross Browser Styling **/
78
+ div.center div.jGrowl-notification, div.center div.jGrowl-closer {
79
+ margin-left: auto;
80
+ margin-right: auto;
81
+ }
82
+
83
+ div.jGrowl div.jGrowl-notification, div.jGrowl div.jGrowl-closer {
84
+ background-color: #000;
85
+ opacity: .85;
86
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)";
87
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=85);
88
+ zoom: 1;
89
+ width: 235px;
90
+ padding: 10px;
91
+ margin-top: 5px;
92
+ margin-bottom: 5px;
93
+ font-family: Tahoma, Arial, Helvetica, sans-serif;
94
+ font-size: 1em;
95
+ text-align: left;
96
+ display: none;
97
+ -moz-border-radius: 5px;
98
+ -webkit-border-radius: 5px;
99
+ }
100
+
101
+ div.jGrowl div.jGrowl-notification {
102
+ min-height: 40px;
103
+ }
104
+
105
+ div.jGrowl div.jGrowl-notification div.jGrowl-header {
106
+ font-weight: bold;
107
+ font-size: .85em;
108
+ }
109
+
110
+ div.jGrowl div.jGrowl-notification div.jGrowl-close {
111
+ z-index: 99;
112
+ float: right;
113
+ font-weight: bold;
114
+ font-size: 1em;
115
+ cursor: pointer;
116
+ }
117
+
118
+ div.jGrowl div.jGrowl-closer {
119
+ padding-top: 4px;
120
+ padding-bottom: 4px;
121
+ cursor: pointer;
122
+ font-size: .9em;
123
+ font-weight: bold;
124
+ text-align: center;
125
+ }
126
+
127
+ /** Hide jGrowl when printing **/
128
+ @media print {
129
+ div.jGrowl {
130
+ display: none;
131
+ }
132
+ }
@@ -0,0 +1,88 @@
1
+ /*------------------------------------*\
2
+ MAIN
3
+ \*------------------------------------*/
4
+ html{
5
+ font-family:"Helvetica Neue", Arial, sans-serif;
6
+ color:#e4eef6;
7
+ background:#4a8ec2;
8
+ background:-moz-linear-gradient(-90deg,#5998c7,#4a8ec2) fixed;
9
+ background:-webkit-gradient(linear,left top,left bottom,from(#5998c7),to(#4a8ec2)) fixed;
10
+ }
11
+ body{
12
+ background:none;
13
+ padding-top:50px;
14
+ text-shadow:0 -1px 0 rgba(0,0,0,0.5), 0 1px 0 rgba(255,255,255,0.25);
15
+ }
16
+ #page{
17
+ margin:0 auto;
18
+ float:none;
19
+ text-align:center;
20
+ }
21
+
22
+
23
+
24
+
25
+
26
+ /*------------------------------------*\
27
+ TYPE
28
+ \*------------------------------------*/
29
+ h1{
30
+ font-weight:bold;
31
+ font-size:3em;
32
+ line-height:1;
33
+ }
34
+ a{
35
+ color:inherit;
36
+ }
37
+
38
+
39
+
40
+
41
+
42
+ /*------------------------------------*\
43
+ IMAGES
44
+ \*------------------------------------*/
45
+ #logo{
46
+ margin-bottom:1.5em;
47
+ }
48
+
49
+
50
+
51
+
52
+
53
+ /*------------------------------------*\
54
+ NARROW
55
+ \*------------------------------------*/
56
+ /*
57
+ CSS for tablets and narrower devices
58
+ */
59
+
60
+
61
+
62
+
63
+
64
+ @media (min-width: 721px) and (max-width: 960px){}
65
+ /*--- END NARROW ---*/
66
+
67
+
68
+
69
+
70
+
71
+ /*------------------------------------*\
72
+ MOBILE
73
+ \*------------------------------------*/
74
+ /*
75
+ CSS for mobile devices.
76
+ Linearise it!
77
+ */
78
+
79
+
80
+
81
+
82
+
83
+ @media (max-width: 720px){
84
+ body{
85
+ font-size:0.75em;
86
+ }
87
+ }
88
+ /*--- END MOBILE ---*/
Binary file
@@ -0,0 +1,12 @@
1
+ $(function(){
2
+ $('a.delete_link').click(function() {
3
+ if ( confirm('Really?') ) {
4
+ var f = $('<form>', { action: this.href, method: 'post' });
5
+ f.append( $('<input>', { type: 'hidden', name: '_method', value: 'delete' }) );
6
+ f.appendTo("body");
7
+ f.submit();
8
+ }
9
+
10
+ return false;
11
+ });
12
+ });
@@ -0,0 +1,11 @@
1
+
2
+ (function($){$.jGrowl=function(m,o){if($('#jGrowl').size()==0)
3
+ $('<div id="jGrowl"></div>').addClass((o&&o.position)?o.position:$.jGrowl.defaults.position).appendTo('body');$('#jGrowl').jGrowl(m,o);};$.fn.jGrowl=function(m,o){if($.isFunction(this.each)){var args=arguments;return this.each(function(){var self=this;if($(this).data('jGrowl.instance')==undefined){$(this).data('jGrowl.instance',$.extend(new $.fn.jGrowl(),{notifications:[],element:null,interval:null}));$(this).data('jGrowl.instance').startup(this);}
4
+ if($.isFunction($(this).data('jGrowl.instance')[m])){$(this).data('jGrowl.instance')[m].apply($(this).data('jGrowl.instance'),$.makeArray(args).slice(1));}else{$(this).data('jGrowl.instance').create(m,o);}});};};$.extend($.fn.jGrowl.prototype,{defaults:{pool:0,header:'',group:'',sticky:false,position:'top-right',glue:'after',theme:'default',themeState:'highlight',corners:'10px',check:250,life:3000,closeDuration:'normal',openDuration:'normal',easing:'swing',closer:true,closeTemplate:'&times;',closerTemplate:'<div>[ close all ]</div>',log:function(e,m,o){},beforeOpen:function(e,m,o){},afterOpen:function(e,m,o){},open:function(e,m,o){},beforeClose:function(e,m,o){},close:function(e,m,o){},animateOpen:{opacity:'show'},animateClose:{opacity:'hide'}},notifications:[],element:null,interval:null,create:function(message,o){var o=$.extend({},this.defaults,o);if(typeof o.speed!=='undefined'){o.openDuration=o.speed;o.closeDuration=o.speed;}
5
+ this.notifications.push({message:message,options:o});o.log.apply(this.element,[this.element,message,o]);},render:function(notification){var self=this;var message=notification.message;var o=notification.options;var notification=$('<div class="jGrowl-notification '+o.themeState+' ui-corner-all'+
6
+ ((o.group!=undefined&&o.group!='')?' '+o.group:'')+'">'+'<div class="jGrowl-close">'+o.closeTemplate+'</div>'+'<div class="jGrowl-header">'+o.header+'</div>'+'<div class="jGrowl-message">'+message+'</div></div>').data("jGrowl",o).addClass(o.theme).children('div.jGrowl-close').bind("click.jGrowl",function(){$(this).parent().trigger('jGrowl.close');}).parent();$(notification).bind("mouseover.jGrowl",function(){$('div.jGrowl-notification',self.element).data("jGrowl.pause",true);}).bind("mouseout.jGrowl",function(){$('div.jGrowl-notification',self.element).data("jGrowl.pause",false);}).bind('jGrowl.beforeOpen',function(){if(o.beforeOpen.apply(notification,[notification,message,o,self.element])!=false){$(this).trigger('jGrowl.open');}}).bind('jGrowl.open',function(){if(o.open.apply(notification,[notification,message,o,self.element])!=false){if(o.glue=='after'){$('div.jGrowl-notification:last',self.element).after(notification);}else{$('div.jGrowl-notification:first',self.element).before(notification);}
7
+ $(this).animate(o.animateOpen,o.openDuration,o.easing,function(){if($.browser.msie&&(parseInt($(this).css('opacity'),10)===1||parseInt($(this).css('opacity'),10)===0))
8
+ this.style.removeAttribute('filter');$(this).data("jGrowl").created=new Date();$(this).trigger('jGrowl.afterOpen');});}}).bind('jGrowl.afterOpen',function(){o.afterOpen.apply(notification,[notification,message,o,self.element]);}).bind('jGrowl.beforeClose',function(){if(o.beforeClose.apply(notification,[notification,message,o,self.element])!=false)
9
+ $(this).trigger('jGrowl.close');}).bind('jGrowl.close',function(){$(this).data('jGrowl.pause',true);$(this).animate(o.animateClose,o.closeDuration,o.easing,function(){$(this).remove();var close=o.close.apply(notification,[notification,message,o,self.element]);if($.isFunction(close))
10
+ close.apply(notification,[notification,message,o,self.element]);});}).trigger('jGrowl.beforeOpen');if(o.corners!=''&&$.fn.corner!=undefined)$(notification).corner(o.corners);if($('div.jGrowl-notification:parent',self.element).size()>1&&$('div.jGrowl-closer',self.element).size()==0&&this.defaults.closer!=false){$(this.defaults.closerTemplate).addClass('jGrowl-closer ui-state-highlight ui-corner-all').addClass(this.defaults.theme).appendTo(self.element).animate(this.defaults.animateOpen,this.defaults.speed,this.defaults.easing).bind("click.jGrowl",function(){$(this).siblings().trigger("jGrowl.beforeClose");if($.isFunction(self.defaults.closer)){self.defaults.closer.apply($(this).parent()[0],[$(this).parent()[0]]);}});};},update:function(){$(this.element).find('div.jGrowl-notification:parent').each(function(){if($(this).data("jGrowl")!=undefined&&$(this).data("jGrowl").created!=undefined&&($(this).data("jGrowl").created.getTime()+parseInt($(this).data("jGrowl").life))<(new Date()).getTime()&&$(this).data("jGrowl").sticky!=true&&($(this).data("jGrowl.pause")==undefined||$(this).data("jGrowl.pause")!=true)){$(this).trigger('jGrowl.beforeClose');}});if(this.notifications.length>0&&(this.defaults.pool==0||$(this.element).find('div.jGrowl-notification:parent').size()<this.defaults.pool))
11
+ this.render(this.notifications.shift());if($(this.element).find('div.jGrowl-notification:parent').size()<2){$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose,this.defaults.speed,this.defaults.easing,function(){$(this).remove();});}},startup:function(e){this.element=$(e).addClass('jGrowl').append('<div class="jGrowl-notification"></div>');this.interval=setInterval(function(){$(e).data('jGrowl.instance').update();},parseInt(this.defaults.check));if($.browser.msie&&parseInt($.browser.version)<7&&!window["XMLHttpRequest"]){$(this.element).addClass('ie6');}},shutdown:function(){$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();clearInterval(this.interval);},close:function(){$(this.element).find('div.jGrowl-notification').each(function(){$(this).trigger('jGrowl.beforeClose');});}});$.jGrowl.defaults=$.fn.jGrowl.prototype.defaults;})(jQuery);
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'rest-assured/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rest-assured"
7
+ s.version = RestAssured::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Artem Avetisyan']
10
+ s.email = ['artem.avetisyan@bbc.co.uk']
11
+ s.homepage = "https://github.com/BBC/rest-assured"
12
+ s.summary = %q{A tool for high level mocking/stubbing HTTP based REST services}
13
+ #s.description = %q{TODO: Write a gem description}
14
+
15
+ s.rubyforge_project = "rest-assured"
16
+ s.required_ruby_version = '>= 1.8.7'
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = ['rest-assured']
21
+ s.require_paths = ['lib']
22
+
23
+ s.add_dependency 'sinatra'
24
+ s.add_dependency 'rack-flash'
25
+ #s.add_dependency 'sinatra-reloader'
26
+ s.add_dependency 'haml'
27
+ s.add_dependency 'sass'
28
+ s.add_dependency 'sinatra-static-assets'
29
+ s.add_dependency 'thin'
30
+ s.add_dependency 'activerecord', '~> 3.0.0'
31
+ s.add_dependency 'sinatra-activerecord'
32
+ s.add_dependency 'sqlite3'
33
+ s.add_dependency 'rake'
34
+ s.add_dependency 'meta_where'
35
+ end
36
+
@@ -0,0 +1,117 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe 'Double routes' do
4
+ let :test_double do
5
+ { :fullpath => '/api/google?a=5', :content => 'some awesome content', :method => 'POST' }
6
+ end
7
+ let :valid_params do
8
+ { 'double[fullpath]' => test_double[:fullpath], 'double[content]' => test_double[:content], 'double[method]' => test_double[:method] }
9
+ end
10
+ let :invalid_params do
11
+ { 'double[fullpath]' => test_double[:fullpath] }
12
+ end
13
+
14
+ describe "through ui", :ui => true do
15
+ it "shows doubles page by default" do
16
+ visit '/'
17
+ current_path.should == '/doubles'
18
+ end
19
+
20
+ it "shows list of doubles" do
21
+ f = Double.create test_double
22
+
23
+ visit '/doubles'
24
+
25
+ page.should have_content(f.fullpath)
26
+ end
27
+
28
+ it "shows form for creating new double" do
29
+ visit '/doubles/new'
30
+
31
+ page.should have_css('#double_fullpath')
32
+ page.should have_css('#double_content')
33
+ page.should have_css('#double_description')
34
+ end
35
+
36
+ it "creates double" do
37
+ post '/doubles', valid_params
38
+ follow_redirect!
39
+
40
+ last_request.fullpath.should == '/doubles'
41
+ last_response.body.should =~ /Double created/
42
+ Double.exists?(test_double).should be true
43
+ end
44
+
45
+ it "reports failure when creating with invalid parameters" do
46
+ post '/doubles', invalid_params
47
+
48
+ last_response.should be_ok
49
+ last_response.body.should =~ /Crumps!.*Content can't be blank/
50
+ end
51
+
52
+ it "brings up double edit form" do
53
+ f = Double.create test_double
54
+ visit "/doubles/#{f.id}/edit"
55
+
56
+ find('#double_fullpath').value.should == f.fullpath
57
+ find('#double_content').value.should == f.content
58
+ end
59
+
60
+ it "updates double" do
61
+ f = Double.create test_double
62
+
63
+ put "/doubles/#{f.id}", 'double[fullpath]' => '/some/other/api'
64
+ follow_redirect!
65
+
66
+ last_request.fullpath.should == '/doubles'
67
+ last_response.body.should =~ /Double updated/
68
+ f.reload.fullpath.should == '/some/other/api'
69
+ end
70
+
71
+ it "chooses active double" do
72
+ f = Double.create test_double.merge!(:active => false)
73
+
74
+ ajax "/doubles/#{f.id}", :as => :put, :active => true
75
+
76
+ last_response.should be_ok
77
+ last_response.body.should == 'Changed'
78
+ end
79
+
80
+ it "deletes double" do
81
+ f = Double.create test_double
82
+
83
+ delete "/doubles/#{f.id}"
84
+ follow_redirect!
85
+
86
+ last_response.should be_ok
87
+ last_response.body.should =~ /Double deleted/
88
+
89
+ Double.exists?(test_double).should be_false
90
+ end
91
+ end
92
+
93
+ describe "through REST api", :ui => false do
94
+ it "creates double" do
95
+ post '/doubles', test_double
96
+
97
+ last_response.should be_ok
98
+ Double.exists?(test_double).should be_true
99
+ end
100
+
101
+ it "reports failure when creating with invalid parameters" do
102
+ post '/doubles', test_double.except(:content)
103
+
104
+ last_response.should_not be_ok
105
+ last_response.body.should =~ /Content can't be blank/
106
+ end
107
+
108
+ it "deletes all doubles" do
109
+ Double.create test_double
110
+
111
+ delete '/doubles/all'
112
+
113
+ last_response.should be_ok
114
+ Double.count.should == 0
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,108 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe 'Redirects routes' do
4
+ let :redirect do
5
+ { :pattern => '/sdf.*', :to => 'http://google.com/api' }
6
+ end
7
+
8
+ let :valid_params do
9
+ { 'redirect[pattern]' => redirect[:pattern], 'redirect[to]' => redirect[:to] }
10
+ end
11
+
12
+ let :invalid_params do
13
+ { 'redirect[to]' => redirect[:to] }
14
+ end
15
+
16
+ context 'via ui', :ui => true do
17
+ it 'shows list of redirects' do
18
+ r = Redirect.create redirect
19
+
20
+ visit '/redirects'
21
+
22
+ page.should have_content(r.pattern)
23
+ page.should have_content(r.to)
24
+ end
25
+
26
+ it "shows form for creating new redirect" do
27
+ visit '/redirects/new'
28
+
29
+ page.should have_css('#redirect_pattern')
30
+ page.should have_css('#redirect_to')
31
+ end
32
+
33
+ it "creates redirect" do
34
+ post '/redirects', valid_params
35
+ follow_redirect!
36
+
37
+ last_request.fullpath.should == '/redirects'
38
+ last_response.body.should =~ /Redirect created/
39
+ Redirect.exists?(redirect).should be true
40
+ end
41
+
42
+ it "reports failure when creating with invalid parameters" do
43
+ post '/redirects', invalid_params
44
+
45
+ last_response.should be_ok
46
+ last_response.body.should =~ /Crumps!.*Pattern can't be blank/
47
+ end
48
+
49
+ it "brings up redirect edit form" do
50
+ r = Redirect.create redirect
51
+ visit "/redirects/#{r.id}/edit"
52
+
53
+ find('#redirect_pattern').value.should == r.pattern
54
+ find('#redirect_to').value.should == r.to
55
+ end
56
+
57
+ it "updates redirect" do
58
+ r = Redirect.create redirect
59
+
60
+ put "/redirects/#{r.id}", 'redirect[to]' => '/some/other/api'
61
+ follow_redirect!
62
+
63
+ last_request.fullpath.should == '/redirects'
64
+ last_response.body.should =~ /Redirect updated/
65
+ r.reload.to.should == '/some/other/api'
66
+ end
67
+
68
+ it "reorders redirects" do
69
+ r1 = Redirect.create! redirect
70
+ r2 = Redirect.create! redirect
71
+
72
+ put "/redirects/reorder", :redirect => [r2.id, r1.id]
73
+
74
+ last_response.should be_ok
75
+ last_response.body.should == 'Changed'
76
+ r1.reload.position.should == 1
77
+ r2.reload.position.should == 0
78
+ end
79
+
80
+ it "deletes redirect" do
81
+ f = Redirect.create redirect
82
+
83
+ delete "/redirects/#{f.id}"
84
+ follow_redirect!
85
+
86
+ last_response.should be_ok
87
+ last_response.body.should =~ /Redirect deleted/
88
+
89
+ Redirect.exists?(redirect).should be_false
90
+ end
91
+ end
92
+
93
+ context 'via api', :ui => false do
94
+ it "creates redirect" do
95
+ post '/redirects', redirect
96
+
97
+ last_response.should be_ok
98
+ Redirect.count.should == 1
99
+ end
100
+
101
+ it "reports failure when creating with invalid parameters" do
102
+ post '/redirects', redirect.except(:pattern)
103
+
104
+ last_response.should_not be_ok
105
+ last_response.body.should =~ /Pattern can't be blank/
106
+ end
107
+ end
108
+ end