fastly-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/lib/fastly-rails.rb +29 -0
  5. data/lib/fastly-rails/action_controller/cache_control_headers.rb +24 -0
  6. data/lib/fastly-rails/action_controller/surrogate_control_headers.rb +20 -0
  7. data/lib/fastly-rails/active_record/surrogate_key.rb +43 -0
  8. data/lib/fastly-rails/client.rb +17 -0
  9. data/lib/fastly-rails/configuration.rb +47 -0
  10. data/lib/fastly-rails/engine.rb +24 -0
  11. data/lib/fastly-rails/errors.rb +5 -0
  12. data/lib/fastly-rails/version.rb +3 -0
  13. data/lib/fastly/purgeable.rb +55 -0
  14. data/test/dummy/README.rdoc +28 -0
  15. data/test/dummy/Rakefile +6 -0
  16. data/test/dummy/app/assets/javascripts/application.js +13 -0
  17. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  18. data/test/dummy/app/controllers/application_controller.rb +5 -0
  19. data/test/dummy/app/controllers/books_controller.rb +66 -0
  20. data/test/dummy/app/helpers/application_helper.rb +2 -0
  21. data/test/dummy/app/models/book.rb +12 -0
  22. data/test/dummy/app/views/books/index.html.erb +2 -0
  23. data/test/dummy/app/views/books/show.html.erb +2 -0
  24. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  25. data/test/dummy/bin/bundle +3 -0
  26. data/test/dummy/bin/rails +4 -0
  27. data/test/dummy/bin/rake +4 -0
  28. data/test/dummy/config.ru +4 -0
  29. data/test/dummy/config/application.rb +23 -0
  30. data/test/dummy/config/boot.rb +5 -0
  31. data/test/dummy/config/database.yml +25 -0
  32. data/test/dummy/config/environment.rb +5 -0
  33. data/test/dummy/config/environments/development.rb +29 -0
  34. data/test/dummy/config/environments/production.rb +80 -0
  35. data/test/dummy/config/environments/test.rb +36 -0
  36. data/test/dummy/config/initializers/_rails_version_check.rb +3 -0
  37. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  39. data/test/dummy/config/initializers/inflections.rb +16 -0
  40. data/test/dummy/config/initializers/mime_types.rb +5 -0
  41. data/test/dummy/config/initializers/secret_token.rb +16 -0
  42. data/test/dummy/config/initializers/session_store.rb +3 -0
  43. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  44. data/test/dummy/config/locales/en.yml +23 -0
  45. data/test/dummy/config/routes.rb +5 -0
  46. data/test/dummy/db/migrate/20140407202136_create_books.rb +9 -0
  47. data/test/dummy/db/schema.rb +22 -0
  48. data/test/dummy/public/404.html +58 -0
  49. data/test/dummy/public/422.html +58 -0
  50. data/test/dummy/public/500.html +57 -0
  51. data/test/dummy/public/favicon.ico +0 -0
  52. data/test/dummy/test/controllers/books_controller_test.rb +38 -0
  53. data/test/dummy/test/factories/books.rb +7 -0
  54. data/test/dummy/test/fixtures/books.yml +7 -0
  55. data/test/dummy/test/integration/fastly_headers_test.rb +91 -0
  56. data/test/dummy/test/models/book_test.rb +41 -0
  57. data/test/fastly-rails/cache_control_headers_test.rb +8 -0
  58. data/test/fastly-rails/client_test.rb +36 -0
  59. data/test/fastly-rails/configuration_test.rb +84 -0
  60. data/test/fastly-rails_test.rb +57 -0
  61. data/test/test_helper.rb +67 -0
  62. metadata +270 -0
@@ -0,0 +1,58 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style>
6
+ body {
7
+ background-color: #EFEFEF;
8
+ color: #2E2F30;
9
+ text-align: center;
10
+ font-family: arial, sans-serif;
11
+ }
12
+
13
+ div.dialog {
14
+ width: 25em;
15
+ margin: 4em auto 0 auto;
16
+ border: 1px solid #CCC;
17
+ border-right-color: #999;
18
+ border-left-color: #999;
19
+ border-bottom-color: #BBB;
20
+ border-top: #B00100 solid 4px;
21
+ border-top-left-radius: 9px;
22
+ border-top-right-radius: 9px;
23
+ background-color: white;
24
+ padding: 7px 4em 0 4em;
25
+ }
26
+
27
+ h1 {
28
+ font-size: 100%;
29
+ color: #730E15;
30
+ line-height: 1.5em;
31
+ }
32
+
33
+ body > p {
34
+ width: 33em;
35
+ margin: 0 auto 1em;
36
+ padding: 1em 0;
37
+ background-color: #F7F7F7;
38
+ border: 1px solid #CCC;
39
+ border-right-color: #999;
40
+ border-bottom-color: #999;
41
+ border-bottom-left-radius: 4px;
42
+ border-bottom-right-radius: 4px;
43
+ border-top-color: #DADADA;
44
+ color: #666;
45
+ box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
46
+ }
47
+ </style>
48
+ </head>
49
+
50
+ <body>
51
+ <!-- This file lives in public/422.html -->
52
+ <div class="dialog">
53
+ <h1>The change you wanted was rejected.</h1>
54
+ <p>Maybe you tried to change something you didn't have access to.</p>
55
+ </div>
56
+ <p>If you are the application owner check the logs for more information.</p>
57
+ </body>
58
+ </html>
@@ -0,0 +1,57 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style>
6
+ body {
7
+ background-color: #EFEFEF;
8
+ color: #2E2F30;
9
+ text-align: center;
10
+ font-family: arial, sans-serif;
11
+ }
12
+
13
+ div.dialog {
14
+ width: 25em;
15
+ margin: 4em auto 0 auto;
16
+ border: 1px solid #CCC;
17
+ border-right-color: #999;
18
+ border-left-color: #999;
19
+ border-bottom-color: #BBB;
20
+ border-top: #B00100 solid 4px;
21
+ border-top-left-radius: 9px;
22
+ border-top-right-radius: 9px;
23
+ background-color: white;
24
+ padding: 7px 4em 0 4em;
25
+ }
26
+
27
+ h1 {
28
+ font-size: 100%;
29
+ color: #730E15;
30
+ line-height: 1.5em;
31
+ }
32
+
33
+ body > p {
34
+ width: 33em;
35
+ margin: 0 auto 1em;
36
+ padding: 1em 0;
37
+ background-color: #F7F7F7;
38
+ border: 1px solid #CCC;
39
+ border-right-color: #999;
40
+ border-bottom-color: #999;
41
+ border-bottom-left-radius: 4px;
42
+ border-bottom-right-radius: 4px;
43
+ border-top-color: #DADADA;
44
+ color: #666;
45
+ box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
46
+ }
47
+ </style>
48
+ </head>
49
+
50
+ <body>
51
+ <!-- This file lives in public/500.html -->
52
+ <div class="dialog">
53
+ <h1>We're sorry, but something went wrong.</h1>
54
+ </div>
55
+ <p>If you are the application owner check the logs for more information.</p>
56
+ </body>
57
+ </html>
File without changes
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ class BooksControllerTest < ActionController::TestCase
4
+
5
+ def setup
6
+ WebMock.stub_request(:any, /.*/).
7
+ to_return(
8
+ :status => 200,
9
+ :body => "{}",
10
+ :message => "{}"
11
+ )
12
+ @no_of_books = 5
13
+ create_list :book, @no_of_books
14
+ end
15
+
16
+ test "index" do
17
+ get :index
18
+ assert_response :success, 'it should return successfully'
19
+ assert_equal @no_of_books, assigns(:books).count, "it should retrieve #{@no_of_books} books"
20
+ end
21
+
22
+ test "show" do
23
+ expected_id = 1
24
+ get :show, {:id => expected_id}
25
+ assert_response :success, 'it should return successfully'
26
+ assert_not_nil assigns(:book), '@book should not be nil'
27
+ assert_instance_of Book, assigns(:book), 'it should be an instance of a book'
28
+ assert_equal expected_id, assigns(:book).id, 'book.id should be the expected id'
29
+ end
30
+
31
+ test "create" do
32
+ expected_name = 'newly-created-book'
33
+ assert_difference('Book.count') do
34
+ post :create, :book => {'name' => expected_name}
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,7 @@
1
+ # Read about factories at https://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :book do
5
+ name { Faker::Movie.title }
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
+
3
+ one:
4
+ name: MyText
5
+
6
+ two:
7
+ name: MyText
@@ -0,0 +1,91 @@
1
+ require 'test_helper'
2
+
3
+ class FastlyHeadersTest < ActionDispatch::IntegrationTest
4
+
5
+ test '/books index page should have fastly headers' do
6
+
7
+ get '/books'
8
+ assert_response :success
9
+
10
+ assert !request.session_options[:skip].nil?
11
+ assert_equal true, request.session_options[:skip]
12
+
13
+ assert response.headers.key?('Cache-Control')
14
+ assert_equal 'public, no-cache', response.headers['Cache-Control']
15
+
16
+ assert response.headers.key?('Surrogate-Control')
17
+ max_age = FastlyRails.configuration.max_age
18
+ assert_equal "max-age=#{max_age}", response.headers['Surrogate-Control']
19
+ end
20
+
21
+ test '/books/:id show page should have fastly headers' do
22
+
23
+ create :book, :id => 1
24
+
25
+ get '/books/1'
26
+ assert_response :success
27
+
28
+ assert !request.session_options[:skip].nil?
29
+ assert_equal true, request.session_options[:skip]
30
+
31
+ assert response.headers.key?('Cache-Control')
32
+ assert_equal 'public, no-cache', response.headers['Cache-Control']
33
+
34
+ assert response.headers.key?('Surrogate-Control')
35
+ max_age = FastlyRails.configuration.max_age
36
+ assert_equal "max-age=#{max_age}", response.headers['Surrogate-Control']
37
+
38
+
39
+ end
40
+
41
+ test 'POST /books should not have fastly headers/ fastly header values' do
42
+
43
+ assert_difference('Book.count') do
44
+ post '/books', 'book' => { 'name' => 'some new book' }
45
+ end
46
+
47
+ assert_nil request.session_options[:skip]
48
+
49
+ assert response.headers.key?('Cache-Control')
50
+ assert_equal 'no-cache', response.headers['Cache-Control']
51
+
52
+ assert !response.headers.key?('Surrogate-Control')
53
+
54
+ end
55
+
56
+ test 'PUT /books/:id should not have fastly headers/ fastly header values' do
57
+
58
+ create :book, :id => 1, :name => 'some new book'
59
+
60
+ put '/books/1', 'id' => 1, 'book' => { 'name' => 'changed book' }
61
+
62
+ assert_equal 'changed book', Book.find(1).name
63
+
64
+ assert_nil request.session_options[:skip]
65
+
66
+ assert response.headers.key?('Cache-Control')
67
+ assert_equal 'no-cache', response.headers['Cache-Control']
68
+
69
+ assert !response.headers.key?('Surrogate-Control')
70
+
71
+ end
72
+
73
+ test 'DELETE /books/:id should not have fastly headers/ fastly header values' do
74
+
75
+ create :book, :id => 1
76
+
77
+ delete '/books/1'
78
+
79
+ assert Book.where(:id => 1).empty?
80
+
81
+ assert_nil request.session_options[:skip]
82
+
83
+ assert response.headers.key?('Cache-Control')
84
+ assert_equal 'no-cache', response.headers['Cache-Control']
85
+
86
+ assert !response.headers.key?('Surrogate-Control')
87
+
88
+ end
89
+
90
+ end
91
+
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ # class BookTest < ActiveSupport::TestCase
4
+ # test "the truth" do
5
+ # assert true
6
+ # end
7
+ # end
8
+
9
+ describe Book do
10
+
11
+ let (:book) { create :book, id: 1 }
12
+
13
+ it "should have Fastly::SurrogateKey instance methods" do
14
+
15
+ [:record_key, :table_key, :purge, :purge_all].each do |method|
16
+ assert_respond_to book, method
17
+ end
18
+
19
+ end
20
+
21
+ it "should have Fastly::SurrogateKey class methods" do
22
+
23
+ [:table_key, :purge_all].each do |method|
24
+ assert_respond_to Book, method
25
+ end
26
+
27
+ end
28
+
29
+ it "should have a record_key of books/1" do
30
+ assert_equal 'books/1', book.record_key
31
+ end
32
+
33
+ it "should have a table_key that returns its table name" do
34
+ assert_equal 'books', book.table_key
35
+ end
36
+
37
+ it "should have class.table_key and instance.table_key that are equivalent" do
38
+ assert_equal Book.table_key, book.table_key
39
+ end
40
+
41
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class FastlyRails::CacheControlHeadersTest < ActiveSupport::TestCase
4
+
5
+ test "sets cache control headers on actioncontroller request" do
6
+
7
+ end
8
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ describe FastlyRails::Client do
4
+
5
+ let(:client) do
6
+ FastlyRails::Client.new(
7
+ :api_key => 'KEY', :user => 'USER', :password => 'PASS'
8
+ )
9
+ end
10
+
11
+ it 'should create a fastly rails client' do
12
+ assert_instance_of FastlyRails::Client, client
13
+ end
14
+
15
+ it 'should be delegated to the fastly client' do
16
+ assert_instance_of Fastly, client.instance_variable_get('@delegate_dc_obj')
17
+ end
18
+
19
+ # This is kind of a static-ish test that technically isn't necessary
20
+ # But if we decide to lock down the methods available from the client
21
+ # through this interface, we can ensure they're available via this test
22
+
23
+ it 'should respond to methods available in the fastly client' do
24
+
25
+ methods = [
26
+ :purge,
27
+ :get_service
28
+ ]
29
+
30
+ methods.each do |method|
31
+ assert_respond_to client, method
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,84 @@
1
+ require 'test_helper'
2
+
3
+ describe FastlyRails::Configuration do
4
+
5
+ let(:configuration) { FastlyRails::Configuration.new }
6
+
7
+ it 'should create a fastly rails client' do
8
+ assert_instance_of FastlyRails::Configuration, configuration
9
+ end
10
+
11
+ it 'should have configuration attributes' do
12
+
13
+ methods = [
14
+ :api_key,
15
+ :user,
16
+ :password,
17
+ :max_age
18
+ ]
19
+
20
+ methods.each do |method|
21
+ assert_respond_to configuration, method
22
+ end
23
+
24
+ end
25
+
26
+ describe 'max_age_default' do
27
+
28
+ it 'should be a class method' do
29
+ assert_respond_to FastlyRails::Configuration, :max_age_default
30
+ end
31
+
32
+ it 'should return the value of a constant MAX_AGE_DEFAULT' do
33
+ assert_equal FastlyRails::Configuration::MAX_AGE_DEFAULT, FastlyRails::Configuration.max_age_default
34
+ end
35
+
36
+ end
37
+
38
+ describe 'authenticatable?' do
39
+
40
+ before do
41
+ configuration.api_key = nil
42
+ configuration.user = nil
43
+ configuration.password = nil
44
+ end
45
+
46
+ it 'should be an instance method' do
47
+ assert_respond_to configuration, :authenticatable?
48
+ end
49
+
50
+ it 'should return false if api_key, user, and password are nil' do
51
+ assert_equal false, configuration.authenticatable?
52
+ end
53
+
54
+ it 'should return false if only user is not nil' do
55
+
56
+ configuration.user = 'user'
57
+
58
+ assert_equal false, configuration.authenticatable?
59
+
60
+ end
61
+
62
+ it 'should return true if only api_key is not nil' do
63
+
64
+ configuration.api_key = 'key'
65
+
66
+ assert_equal true, configuration.authenticatable?
67
+
68
+ end
69
+
70
+ it 'should return true if if user and password are not nil' do
71
+
72
+ configuration.user = 'user'
73
+ configuration.password = 'password'
74
+
75
+ assert_equal true, configuration.authenticatable?
76
+
77
+ end
78
+ end
79
+
80
+ it 'should have a default value for max_age since none was provided' do
81
+ assert_equal FastlyRails::Configuration.max_age_default, configuration.max_age
82
+ end
83
+
84
+ end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ describe FastlyRails do
4
+
5
+ let(:api_key) { 'test' }
6
+ let(:user) { nil }
7
+ let(:password) { nil }
8
+ let(:max_age) { 100000 }
9
+ let(:configuration) { FastlyRails.configuration }
10
+ let(:client) { FastlyRails.client }
11
+
12
+ it 'should be a module' do
13
+ assert_kind_of Module, FastlyRails
14
+ end
15
+
16
+ describe 'credentials not provided' do
17
+
18
+ it 'should raise an error if configuration is not authenticatable' do
19
+
20
+ assert_equal false, configuration.authenticatable?
21
+ assert_raises FastlyRails::NoAuthCredentialsProvidedError do
22
+ client
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ describe 'credentials provided' do
30
+
31
+ before do
32
+
33
+ FastlyRails.configure do |c|
34
+ c.api_key = api_key
35
+ c.user = user
36
+ c.password = password
37
+ c.max_age = max_age
38
+ end
39
+
40
+ end
41
+
42
+
43
+ it 'should have configuration options set up' do
44
+
45
+ assert_equal api_key, configuration.api_key
46
+ assert_equal user, configuration.user
47
+ assert_equal password, configuration.password
48
+ assert_equal max_age, configuration.max_age
49
+
50
+ end
51
+
52
+ it 'should return a valid client' do
53
+ assert_instance_of FastlyRails::Client, client
54
+ end
55
+
56
+ end
57
+ end