cathode 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +236 -0
- data/Rakefile +26 -0
- data/app/assets/javascripts/cathode/application.js +13 -0
- data/app/assets/stylesheets/cathode/application.css +13 -0
- data/app/controllers/cathode/base_controller.rb +47 -0
- data/app/helpers/cathode/application_helper.rb +4 -0
- data/app/views/layouts/cathode/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/cathode.rb +14 -0
- data/lib/cathode/_version.rb +3 -0
- data/lib/cathode/action.rb +82 -0
- data/lib/cathode/base.rb +28 -0
- data/lib/cathode/engine.rb +5 -0
- data/lib/cathode/exceptions.rb +3 -0
- data/lib/cathode/request.rb +15 -0
- data/lib/cathode/resource.rb +40 -0
- data/lib/cathode/version.rb +49 -0
- data/lib/tasks/cathode_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/api/dummy_api.rb +4 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/product.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +28 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20140404222551_create_products.rb +10 -0
- data/spec/dummy/db/schema.rb +23 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +312 -0
- data/spec/dummy/log/test.log +12708 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/factories/products.rb +8 -0
- data/spec/integration/api_spec.rb +88 -0
- data/spec/lib/action_spec.rb +140 -0
- data/spec/lib/base_spec.rb +28 -0
- data/spec/lib/request_spec.rb +5 -0
- data/spec/lib/resources_spec.rb +78 -0
- data/spec/lib/versioning_spec.rb +104 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/support/factories/products.rb +3 -0
- data/spec/support/helpers.rb +9 -0
- metadata +259 -0
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            <!DOCTYPE html>
         | 
| 2 | 
            +
            <html>
         | 
| 3 | 
            +
            <head>
         | 
| 4 | 
            +
              <title>The page you were looking for doesn't exist (404)</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/404.html -->
         | 
| 52 | 
            +
              <div class="dialog">
         | 
| 53 | 
            +
                <h1>The page you were looking for doesn't exist.</h1>
         | 
| 54 | 
            +
                <p>You may have mistyped the address or the page may have moved.</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,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,88 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            def make_request(method, path, params = nil, version = '1.0.0')
         | 
| 4 | 
            +
              send(method, path, params, { 'Accept-Version' => version })
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            describe 'API' do
         | 
| 8 | 
            +
              context 'with the default API (all actions)' do
         | 
| 9 | 
            +
                before(:all) do
         | 
| 10 | 
            +
                  use_api do
         | 
| 11 | 
            +
                    version 1.5 do
         | 
| 12 | 
            +
                      resource :products, actions: [:all]
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                let!(:products) { create_list(:product, 5) }
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                describe 'GET #index' do
         | 
| 20 | 
            +
                  subject { make_request :get, 'api/products' }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  it 'responds with all records' do
         | 
| 23 | 
            +
                    subject
         | 
| 24 | 
            +
                    expect(response.body).to eq(products.to_json)
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                describe 'GET #show' do
         | 
| 29 | 
            +
                  subject { make_request :get, 'api/products/1', nil, '1.5' }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  it 'responds with the record' do
         | 
| 32 | 
            +
                    subject
         | 
| 33 | 
            +
                    expect(response.body).to eq(products.first.to_json)
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                describe 'POST #create' do
         | 
| 38 | 
            +
                  subject { make_request :post, 'api/products', product: { title: 'hello', cost: 1900 } }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  it 'responds with the new record' do
         | 
| 41 | 
            +
                    subject
         | 
| 42 | 
            +
                    expect(response.body).to eq(Product.new(title: 'hello', cost: 1900).to_json)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                describe 'DELETE #destroy' do
         | 
| 47 | 
            +
                  subject { make_request :delete, 'api/products/1' }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  it 'responds with success' do
         | 
| 50 | 
            +
                    expect(subject).to eq(200)
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              context 'with an access filter' do
         | 
| 56 | 
            +
                subject { make_request :get, 'api/products/1' }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                let!(:products) { create_list(:product, 5) }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                context 'when inaccessible' do
         | 
| 61 | 
            +
                  before(:all) do
         | 
| 62 | 
            +
                    use_api do
         | 
| 63 | 
            +
                      resource :products do
         | 
| 64 | 
            +
                        action(:show) { access_filter { false } }
         | 
| 65 | 
            +
                      end
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  it 'responds with unauthorized' do
         | 
| 70 | 
            +
                    expect(subject).to eq(401)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                context 'when accessible' do
         | 
| 75 | 
            +
                  before(:all) do
         | 
| 76 | 
            +
                    use_api do
         | 
| 77 | 
            +
                      resource :products do
         | 
| 78 | 
            +
                        action(:show) { access_filter { true } }
         | 
| 79 | 
            +
                      end
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  it 'responds with success' do
         | 
| 84 | 
            +
                    expect(subject).to eq(200)
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
            end
         | 
| @@ -0,0 +1,140 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Cathode::Action do
         | 
| 4 | 
            +
              describe '.create' do
         | 
| 5 | 
            +
                subject { Cathode::Action.create(action, :products) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                context 'with :index' do
         | 
| 8 | 
            +
                  let(:action) { :index }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  it 'creates a IndexAction' do
         | 
| 11 | 
            +
                    expect(subject.class).to eq(Cathode::IndexAction)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                context 'with :show' do
         | 
| 16 | 
            +
                  let(:action) { :show }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  it 'creates a ShowAction' do
         | 
| 19 | 
            +
                    expect(subject.class).to eq(Cathode::ShowAction)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                context 'with :create' do
         | 
| 24 | 
            +
                  let(:action) { :create }
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  it 'creates a CreateAction' do
         | 
| 27 | 
            +
                    expect(subject.class).to eq(Cathode::CreateAction)
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                context 'with :update' do
         | 
| 32 | 
            +
                  let(:action) { :update }
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  it 'creates an UpdateAction' do
         | 
| 35 | 
            +
                    expect(subject.class).to eq(Cathode::UpdateAction)
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                context 'with :destroy' do
         | 
| 40 | 
            +
                  let(:action) { :destroy }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  it 'creates a DestroyAction' do
         | 
| 43 | 
            +
                    expect(subject.class).to eq(Cathode::DestroyAction)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              describe '#perform' do
         | 
| 49 | 
            +
                let!(:products) { create_list(:product, 5) }
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                subject { Cathode::Action.create(action, :products).perform(params) }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                context ':index' do
         | 
| 54 | 
            +
                  let(:action) { :index }
         | 
| 55 | 
            +
                  let(:params) { {} }
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  it 'sets status as ok' do
         | 
| 58 | 
            +
                    expect(subject[:status]).to eq(:ok)
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  it 'sets body as all resource records' do
         | 
| 62 | 
            +
                    expect(subject[:body]).to eq(Product.all)
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                context ':show' do
         | 
| 67 | 
            +
                  let(:action) { :show }
         | 
| 68 | 
            +
                  let(:params) { { :id => 3 } }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  subject { Cathode::Action.create(action, :products, &block).perform(params) }
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  context 'with access filter' do
         | 
| 73 | 
            +
                    context 'when accessible' do
         | 
| 74 | 
            +
                      let(:block) { proc { access_filter(&proc { true }) } }
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                      it 'sets status as ok' do
         | 
| 77 | 
            +
                        expect(subject[:status]).to eq(:ok)
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                      it 'sets body as the record' do
         | 
| 81 | 
            +
                        expect(subject[:body]).to eq(products[2])
         | 
| 82 | 
            +
                      end
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                    context 'when inaccessible' do
         | 
| 86 | 
            +
                      let(:block) { proc { access_filter(&proc { false }) } }
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      it 'sets status as unauthorized' do
         | 
| 89 | 
            +
                        expect(subject[:status]).to eq(:unauthorized)
         | 
| 90 | 
            +
                      end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                      it 'sets body as nil' do
         | 
| 93 | 
            +
                        expect(subject[:body]).to be_nil
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
                    end
         | 
| 96 | 
            +
                  end
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                context ':create' do
         | 
| 100 | 
            +
                  let(:action) { :create }
         | 
| 101 | 
            +
                  let(:params) { { :title => 'cool product' } }
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  it 'sets status as ok' do
         | 
| 104 | 
            +
                    expect(subject[:status]).to eq(:ok)
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  it 'sets body as the new record' do
         | 
| 108 | 
            +
                    expect(subject[:body].title).to eq('cool product')
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                context ':update' do
         | 
| 113 | 
            +
                  let(:action) { :update }
         | 
| 114 | 
            +
                  let(:params) { { :id => product.id, :title => 'cooler product' } }
         | 
| 115 | 
            +
                  let(:product) { create(:product, title: 'cool product') }
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  it 'sets status as ok' do
         | 
| 118 | 
            +
                    expect(subject[:status]).to eq(:ok)
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                  it 'sets body as the updated record' do
         | 
| 122 | 
            +
                    expect(subject[:body].title).to eq('cooler product')
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                context ':destroy' do
         | 
| 127 | 
            +
                  let(:action) { :destroy }
         | 
| 128 | 
            +
                  let(:params) { { :id => product.id } }
         | 
| 129 | 
            +
                  let!(:product) { create(:product) }
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                  it 'sets status as ok' do
         | 
| 132 | 
            +
                    expect(subject[:status]).to eq(:ok)
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  it 'removes the record' do
         | 
| 136 | 
            +
                    expect { subject }.to change { Product.count }.by(-1)
         | 
| 137 | 
            +
                  end
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
              end
         | 
| 140 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Cathode::Base do
         | 
| 4 | 
            +
              describe '#version' do
         | 
| 5 | 
            +
                subject { Cathode::Base.version 1.5 do
         | 
| 6 | 
            +
                  resource :products
         | 
| 7 | 
            +
                end }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                it 'creates a new version' do
         | 
| 10 | 
            +
                  expect(subject.version).to eq('1.5.0')
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                it 'contains the resources' do
         | 
| 14 | 
            +
                  expect(subject.resources.keys).to eq([:products])
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              describe '#resource' do
         | 
| 19 | 
            +
                context 'with resource name' do
         | 
| 20 | 
            +
                  subject { Cathode::Base.resource(:products) }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  it 'initializes version 1.0.0' do
         | 
| 23 | 
            +
                    subject
         | 
| 24 | 
            +
                    expect(Cathode::Version.all['1.0.0'].resources[:products]).to_not be_nil
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         |