├── log └── .keep ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── public ├── favicon.ico ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── app ├── assets │ ├── images │ │ └── .keep │ ├── stylesheets │ │ └── application.css.scss │ └── javascripts │ │ └── application.js ├── controllers │ ├── concerns │ │ └── .keep │ ├── settings_controller.rb │ ├── images_controller.rb │ ├── application_controller.rb │ ├── categories_controller.rb │ └── posts_controller.rb ├── models │ ├── image.rb │ ├── category.rb │ ├── post.rb │ ├── contentful │ │ ├── file_with_locale.rb │ │ ├── asset.rb │ │ └── entity.rb │ └── settings.rb ├── views │ ├── categories │ │ ├── edit.html.slim │ │ ├── new.html.slim │ │ ├── _form.html.slim │ │ └── index.html.slim │ ├── posts │ │ ├── show.html.slim │ │ ├── index.html.slim │ │ ├── new.html.slim │ │ └── edit.html.slim │ ├── images │ │ ├── new.html.slim │ │ ├── edit.html.slim │ │ └── index.html.slim │ ├── settings │ │ ├── new.html.slim │ │ └── edit.html.slim │ └── layouts │ │ └── application.html.slim └── helpers │ ├── application_helper.rb │ └── contentful_helper.rb ├── .ruby-gemset ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── .rspec ├── bin ├── rake ├── bundle └── rails ├── config.ru ├── config ├── environment.rb ├── initializers │ ├── session_store.rb │ ├── filter_parameter_logging.rb │ ├── mime_types.rb │ ├── backtrace_silencers.rb │ ├── wrap_parameters.rb │ ├── inflections.rb │ └── secret_token.rb ├── boot.rb ├── routes.rb ├── database.yml ├── locales │ └── en.yml ├── application.rb └── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── spec ├── factories │ └── setting.rb ├── support │ └── vcr.rb ├── controllers │ ├── settings_controller_spec.rb │ ├── categories_controller_spec.rb │ ├── images_controller_spec.rb │ └── posts_controller_spec.rb ├── rails_helper.rb ├── spec_helper.rb └── fixtures │ └── vcr_cassettes │ ├── image │ ├── new.yml │ └── destroy.yml │ ├── category │ ├── destroy.yml │ └── update.yml │ └── post │ └── destroy.yml ├── Rakefile ├── db ├── migrate │ └── 20140820104626_create_settings.rb ├── seeds.rb └── schema.rb ├── Gemfile ├── .gitignore ├── LICENSE ├── README.md └── Gemfile.lock /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | cma_demo_app -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /app/models/image.rb: -------------------------------------------------------------------------------- 1 | class Image < Contentful::Asset 2 | 3 | end -------------------------------------------------------------------------------- /app/views/categories/edit.html.slim: -------------------------------------------------------------------------------- 1 | h1 Edit Category 2 | = render 'form' 3 | -------------------------------------------------------------------------------- /app/views/categories/new.html.slim: -------------------------------------------------------------------------------- 1 | h1 Add new Category 2 | = render 'form' 3 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css.scss: -------------------------------------------------------------------------------- 1 | @import "bootstrap-sprockets"; 2 | @import "bootstrap"; -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /app/models/category.rb: -------------------------------------------------------------------------------- 1 | class Category < Contentful::Entity 2 | 3 | content_type :category_content_type 4 | 5 | end 6 | -------------------------------------------------------------------------------- /app/models/post.rb: -------------------------------------------------------------------------------- 1 | class Post < Contentful::Entity 2 | 3 | content_type :post_content_type 4 | 5 | has_one :category 6 | 7 | end -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | CmaDemoApp::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | CmaDemoApp::Application.config.session_store :cookie_store, key: '_cma_demo_app_session' 4 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 5 | -------------------------------------------------------------------------------- /spec/factories/setting.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :settings do 3 | access_token '' 4 | organization_id '' 5 | space_id 'v2umtz8ths9v' 6 | end 7 | end -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | CmaDemoApp::Application.load_tasks 7 | -------------------------------------------------------------------------------- /db/migrate/20140820104626_create_settings.rb: -------------------------------------------------------------------------------- 1 | class CreateSettings < ActiveRecord::Migration 2 | def change 3 | create_table :settings do |t| 4 | t.string :access_token 5 | t.string :organization_id 6 | t.string :space_id 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/posts/show.html.slim: -------------------------------------------------------------------------------- 1 | h1 #{@post.title_en_us} 2 | 3 | p author: #{@post.author_en_us} 4 | p #{@post.body_en_us} 5 | = image_tag get_image(@post.title_image_en_us_id) 6 | | #{" "} 7 | = image_tag get_image(@post.second_image_en_us_id) 8 | br 9 | br 10 | = link_to 'Back',posts_path, class: 'btn btn-default' 11 | 12 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | 3 | def alert_class_for(flash_type) 4 | { 5 | :success => 'alert-success', 6 | :error => 'alert-danger', 7 | :alert => 'alert-warning', 8 | :notice => 'alert-info' 9 | }[flash_type.to_sym] || flash_type.to_s 10 | end 11 | 12 | end -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /app/views/images/new.html.slim: -------------------------------------------------------------------------------- 1 | h1 New Asset 2 | = contentful_form_for @image do |f| 3 | - @image.form_field_names.each do |field_name| 4 | - unless field_name.match(/\Afile_(?!type|url)/) 5 | .form-group 6 | = f.label field_name 7 | = f.text_field field_name, class: 'form-control' 8 | = f.submit 'Save', class: 'btn btn-primary' 9 | 10 | 11 | -------------------------------------------------------------------------------- /spec/support/vcr.rb: -------------------------------------------------------------------------------- 1 | require 'vcr' 2 | 3 | VCR.configure do |c| 4 | c.cassette_library_dir = 'spec/fixtures/vcr_cassettes' 5 | c.ignore_localhost = true 6 | c.hook_into :webmock 7 | c.default_cassette_options = {record: :once} 8 | end 9 | 10 | def vcr(name, &block) 11 | VCR.use_cassette(name, &block) 12 | end 13 | 14 | def expect_vcr(name, &block) 15 | expect { VCR.use_cassette(name, &block) } 16 | end -------------------------------------------------------------------------------- /app/views/settings/new.html.slim: -------------------------------------------------------------------------------- 1 | h1 Settings 2 | = form_for @settings, url: { action: :create }, role: 'form' do |f| 3 | .form-group 4 | = f.label :access_token 5 | = f.text_field :access_token, class: 'form-control' 6 | .form-group 7 | = f.label :organization_id, 'Organization id' 8 | = f.text_field :organization_id, class: 'form-control' 9 | = f.submit 'Save and Setup', class: 'btn btn-default' 10 | -------------------------------------------------------------------------------- /app/views/categories/_form.html.slim: -------------------------------------------------------------------------------- 1 | = contentful_form_for @category do |f| 2 | - @category.form_field_names.each do |field_name, type| 3 | .form-group 4 | - if type != 'Boolean' 5 | = f.label field_name 6 | = f.text_field field_name, class: 'form-control' 7 | - else 8 | = f.label field_name 9 | = f.check_box field_name, class: 'form-control' 10 | = f.submit 'Save', class: 'btn btn-primary' -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | CmaDemoApp::Application.routes.draw do 2 | 3 | resource :settings, except: [:show, :index, :delete] 4 | 5 | resources :categories, except: [:show] do 6 | get :toggle_status, on: :member 7 | end 8 | resources :posts do 9 | get :toggle_status, on: :member 10 | end 11 | 12 | resources :images, except: [:show] do 13 | get :toggle_status, on: :member 14 | end 15 | 16 | root to: 'posts#index' 17 | 18 | end 19 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /app/views/images/edit.html.slim: -------------------------------------------------------------------------------- 1 | h1 Edit Asset 2 | = contentful_form_for @image do |f| 3 | - @image.form_field_names.each do |field_name| 4 | - if field_name.match(/\Afile_(?!type|url)/) 5 | .file 6 | = f.label field_name 7 | br 8 | = image_tag @image.form_image_url(w:250, h:250, field: field_name), class: 'img-thumbnail' 9 | - else 10 | .form-group 11 | = f.label field_name 12 | = f.text_field field_name, class: 'form-control' 13 | = f.submit 'Save', class: 'btn btn-primary' 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/views/settings/edit.html.slim: -------------------------------------------------------------------------------- 1 | h1 Settings 2 | = form_for @settings, url: { action: :update }, role: 'form' do |f| 3 | .form-group 4 | = f.label :access_token 5 | = f.text_field :access_token, class: 'form-control' 6 | .form-group 7 | = f.label :organization_id, 'Organization id' 8 | = f.text_field :organization_id, class: 'form-control', readonly: true 9 | .form-group 10 | = f.label :space_id, 'Space id' 11 | = f.text_field :space_id, class: 'form-control', readonly: true 12 | = f.submit 'Save', class: 'btn btn-default' 13 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure your secret_key_base is kept private 11 | # if you're sharing your code publicly. 12 | CmaDemoApp::Application.config.secret_key_base = '29490aa1977e721491df319ab47a80e7d17e469962c99daa79692a4fb92c7526894fbe23752d178ba311b5f51d5d086043c18d220f65be3c832d91dc7763dbcb' 13 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require bootstrap-sprockets 16 | //= require_tree . 17 | -------------------------------------------------------------------------------- /app/helpers/contentful_helper.rb: -------------------------------------------------------------------------------- 1 | module ContentfulHelper 2 | 3 | def contentful_form_for(object, *args, &block) 4 | options = args.extract_options! 5 | new = object.ct_object.nil? 6 | options.merge!(url: {action: new ? :create : :update}) 7 | options.merge!(method: new ? :post : :put) 8 | 9 | form_for(object, *(args << options), &block) 10 | end 11 | 12 | def published_object(object) 13 | object.ct_object.published? 14 | end 15 | 16 | def get_image(object) 17 | @images.each do |image| 18 | if image.id == object && object.present? 19 | return image.image_url(h: 250, w: 200) 20 | end 21 | end 22 | nil 23 | end 24 | 25 | def convert_boolean_value(value) 26 | value ? 'Yes' : 'No' 27 | end 28 | 29 | end -------------------------------------------------------------------------------- /spec/controllers/settings_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe SettingsController do 4 | 5 | let!(:settings) { create(:settings) } 6 | 7 | it 'create' do 8 | vcr('settings/create') do 9 | post :create, settings: {access_token: '', 10 | organization_id: ''} 11 | expect(response.status).to eq 302 12 | response.should redirect_to posts_path 13 | end 14 | end 15 | 16 | it 'new' do 17 | get :new 18 | expect(response.status).to eq 200 19 | response.should render_template :new 20 | end 21 | 22 | it 'update' do 23 | put :update, settings: {access_token: 'ACCESS_TOKEN'} 24 | expect(response.status).to eq 302 25 | response.should redirect_to posts_path 26 | end 27 | 28 | end -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby '2.1.2' 4 | 5 | gem 'rails', '4.0.3' 6 | 7 | gem 'sqlite3' 8 | 9 | gem 'bootstrap-sass', '~> 3.2.0' 10 | gem 'sass-rails', '~> 4.0.1' 11 | 12 | gem 'slim-rails', '2.1.5' 13 | 14 | gem 'contentful-management', path: '/Users/piotrprotas/Documents/RUBY_CONTENTUL/contentful-management.rb' 15 | 16 | gem 'uglifier', '>= 1.3.0' 17 | gem 'coffee-rails', '~> 4.0.0' 18 | gem 'jquery-rails' 19 | gem 'jbuilder', '~> 1.2' 20 | 21 | gem 'api_cache' 22 | 23 | group :development do 24 | gem 'thin' 25 | end 26 | 27 | group :test do 28 | gem 'rspec-rails', '~> 3.0.0' 29 | gem 'vcr' 30 | gem 'webmock' 31 | gem 'simplecov', require: false 32 | gem 'factory_girl_rails', '4.4.1' 33 | gem 'shoulda', '3.5.0' 34 | end 35 | 36 | group :doc do 37 | gem 'sdoc', require: false 38 | end 39 | 40 | -------------------------------------------------------------------------------- /app/controllers/settings_controller.rb: -------------------------------------------------------------------------------- 1 | class SettingsController < ApplicationController 2 | 3 | skip_before_action :check_setup, only: [:new, :create] 4 | 5 | def new 6 | @settings = Settings.new 7 | end 8 | 9 | def create 10 | @settings = Settings.new(params.require(:settings).permit(:access_token, :organization_id)) 11 | if @settings.save 12 | @settings.setup 13 | redirect_to posts_path 14 | else 15 | flash[:error] = @settings.errors.full_messages.join('
') 16 | render :new 17 | end 18 | end 19 | 20 | def edit 21 | end 22 | 23 | def update 24 | if @settings.update(params.require(:settings).permit(:access_token)) 25 | redirect_to posts_path 26 | else 27 | flash[:error] = @settings.errors.full_messages.join('
') 28 | render :edit 29 | end 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | /.config 4 | /coverage/ 5 | /InstalledFiles 6 | /pkg/ 7 | /spec/reports/ 8 | /test/tmp/ 9 | /test/version_tmp/ 10 | /tmp/ 11 | 12 | ## Specific to RubyMotion: 13 | .dat* 14 | .repl_history 15 | build/ 16 | 17 | ## Documentation cache and generated files: 18 | /.yardoc/ 19 | /_yardoc/ 20 | /doc/ 21 | /rdoc/ 22 | 23 | ## Environment normalisation: 24 | /.bundle/ 25 | /lib/bundler/man/ 26 | 27 | # for a library or gem, you might want to ignore these files since the code is 28 | # intended to run in multiple environments; otherwise, check them in: 29 | # Gemfile.lock 30 | # .ruby-version 31 | # .ruby-gemset 32 | 33 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 34 | .rvmrc 35 | 36 | .idea 37 | .idea/**/* 38 | 39 | # Databases 40 | db/development.sqlite3 41 | db/test.sqlite3 42 | log/development.log 43 | log/test.log 44 | 45 | .DS_Store -------------------------------------------------------------------------------- /app/views/images/index.html.slim: -------------------------------------------------------------------------------- 1 | h1 Images 2 | table.table.striped.table-hover 3 | thead 4 | tr 5 | th Title 6 | th Description 7 | th File 8 | th Actions 9 | tbody 10 | - @images.each do |image| 11 | tr 12 | td.title 13 | = image.title_en_us 14 | td.description 15 | = image.description_en_us 16 | td.file 17 | = image_tag image.try(:image_url, w: 200, h: 200), class: 'img-thumbnail' 18 | td.actions 19 | = link_to ' Edit ', edit_image_path(image.id) 20 | - if published_object(image) 21 | = link_to ' Unpublish ', toggle_status_image_path(image.id) 22 | - else 23 | = link_to ' Delete ', image_path(image.id), {method: :delete, data: {confirm: "Delete #{image.title}?"}} 24 | = link_to ' Publish ', toggle_status_image_path(image.id) -------------------------------------------------------------------------------- /app/views/categories/index.html.slim: -------------------------------------------------------------------------------- 1 | h1 Categories 2 | table.table.striped.table-hover 3 | thead 4 | tr 5 | th Name 6 | th Description 7 | th Actions 8 | th Published 9 | tbody 10 | - @categories.each do |category| 11 | tr 12 | td.name 13 | = category.name_en_us 14 | td.description 15 | = category.description_en_us 16 | td.actions 17 | = link_to ' Edit ', edit_category_path(category.id) 18 | - if published_object(category) 19 | = link_to 'Unpublish ' , toggle_status_category_path(category.id) 20 | - else 21 | = link_to ' Delete ', category_path(category.id), {method: :delete, data: {confirm: "Delete #{category.name_en_us}?"}} 22 | = link_to ' Publish ' , toggle_status_category_path(category.id) 23 | td.published 24 | = convert_boolean_value(category.ct_object.published?) -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(:default, Rails.env) 8 | 9 | module CmaDemoApp 10 | class Application < Rails::Application 11 | # Settings in config/environments/* take precedence over those specified here. 12 | # Application configuration should go into files in config/initializers 13 | # -- all .rb files in that directory are automatically loaded. 14 | 15 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 16 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 17 | # config.time_zone = 'Central Time (US & Canada)' 18 | 19 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 20 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 21 | # config.i18n.default_locale = :de 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20140820104626) do 15 | 16 | create_table "settings", force: true do |t| 17 | t.string "access_token" 18 | t.string "organization_id" 19 | t.string "space_id" 20 | t.datetime "created_at" 21 | t.datetime "updated_at" 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Contentful 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/views/posts/index.html.slim: -------------------------------------------------------------------------------- 1 | h1 Posts 2 | table.table.striped.table-hover 3 | thead 4 | tr 5 | th Title 6 | th Author 7 | th Body 8 | th Category 9 | th Actions 10 | th Published 11 | tbody 12 | - @posts.each do |post| 13 | tr 14 | td.title 15 | = post.title_en_us 16 | td.author 17 | = post.author_en_us 18 | td.body 19 | = post.body_en_us 20 | td.category 21 | = link_to post.category(@space).try(:name), post.category_en_us_id.nil? ? '' : edit_category_path(post.category_en_us_id) 22 | td.actions 23 | = link_to ' Show ', post_path(post.id) 24 | = link_to ' Edit ', edit_post_path(post.id) 25 | - if published_object(post) 26 | = link_to 'Unpublish ', toggle_status_post_path(post.id) 27 | - else 28 | = link_to ' Delete ', post_path(post.id), {method: :delete, data: {confirm: "Delete #{post.title_en_us}?"}} 29 | = link_to ' Publish ', toggle_status_post_path(post.id) 30 | 31 | td.published 32 | = convert_boolean_value(post.ct_object.published?) 33 | 34 | -------------------------------------------------------------------------------- /app/views/posts/new.html.slim: -------------------------------------------------------------------------------- 1 | h1 Add new post 2 | = form_for @post do |f| 3 | - @post.content_type.fields.each do |field| 4 | - @post.locales.each do |locale| 5 | - if @space.default_locale == locale.code || field.localized 6 | .form-group 7 | - if field.link_type == 'Asset' 8 | = f.label "#{field.name.downcase}_#{locale.code.underscore.downcase}" 9 | = f.collection_select "#{field.id.downcase}_#{locale.code.underscore.downcase}_id", @images ,:id, "title_#{locale.code.underscore.downcase}", { include_blank: ''}, class: 'form-control' 10 | - elsif field.link_type == 'Entry' 11 | = f.label "#{field.name.downcase}_#{locale.code.underscore.downcase}" 12 | = f.collection_select "#{field.name.downcase}_#{locale.code.underscore.downcase}_id", @categories ,:id,"name_#{locale.code.underscore.downcase}" , { include_blank: ''}, class: 'form-control' 13 | - else 14 | = f.label "#{field.name.downcase}_#{locale.code.underscore.downcase}" 15 | = f.text_field "#{field.name.downcase}_#{locale.code.underscore.downcase}", class: 'form-control' 16 | = f.submit 'Create', class: 'btn btn-primary' 17 | -------------------------------------------------------------------------------- /app/views/posts/edit.html.slim: -------------------------------------------------------------------------------- 1 | h1 Add new post 2 | = form_for @post, url: { action: :update }, method: :put do |f| 3 | - @post.content_type.fields.each do |field| 4 | - @post.locales.each do |locale| 5 | - if @space.default_locale == locale.code || field.localized 6 | .form-group 7 | - if field.link_type == 'Asset' 8 | = f.label "#{field.name.downcase}_#{locale.code.underscore.downcase}" 9 | = f.collection_select "#{field.id.downcase}_#{locale.code.underscore.downcase}_id", @images ,:id, "title_#{locale.code.underscore.downcase}", { include_blank: ''}, class: 'form-control' 10 | - elsif field.link_type == 'Entry' 11 | = f.label "#{field.name.downcase}_#{locale.code.underscore.downcase}" 12 | = f.collection_select "#{field.name.downcase}_#{locale.code.underscore.downcase}_id", @categories ,:id,"name_#{locale.code.underscore.downcase}" , { include_blank: ''}, class: 'form-control' 13 | - else 14 | = f.label "#{field.name.downcase}_#{locale.code.underscore.downcase}" 15 | = f.text_field "#{field.name.downcase}_#{locale.code.underscore.downcase}", class: 'form-control' 16 | = f.submit 'Update', class: 'btn btn-primary' 17 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | CmaDemoApp::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | end 31 | -------------------------------------------------------------------------------- /app/controllers/images_controller.rb: -------------------------------------------------------------------------------- 1 | class ImagesController < ApplicationController 2 | 3 | before_action :find_space 4 | before_action :find_asset, only: [:edit, :update, :destroy, :toggle_status] 5 | 6 | def index 7 | @images = Image.all(@space) 8 | end 9 | 10 | def new 11 | @image = Image.new({space: @space}) 12 | end 13 | 14 | def create 15 | @image = Image.new(params[:image].merge(space: @space)) 16 | if @image.save(@space) 17 | redirect_to images_path, notice: 'Successfully created!' 18 | else 19 | redirect_to images_path, notice: "#{display_errors}" 20 | end 21 | end 22 | 23 | def edit 24 | end 25 | 26 | def update 27 | @image.update(params[:image]) 28 | redirect_to images_path 29 | end 30 | 31 | def destroy 32 | @image.destroy 33 | redirect_to images_path, notice: 'Successfully deleted!' 34 | end 35 | 36 | def toggle_status 37 | msg = @image.ct_object.published? ? unpublish_object(@image) : publish_object(@image) 38 | redirect_to images_path, notice: msg 39 | end 40 | 41 | private 42 | 43 | def find_asset 44 | @image = Image.find(@space, params[:id]) 45 | end 46 | 47 | def display_errors 48 | @image.errors_contentful.join(', ') 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /app/models/contentful/file_with_locale.rb: -------------------------------------------------------------------------------- 1 | module Contentful 2 | class FileWithLocale 3 | 4 | attr_accessor :object, :locale, :params 5 | 6 | def initialize(object, locale, params={}) 7 | @object, @locale, @params = object, locale, params 8 | end 9 | 10 | # Returns converted locale code. e.g "en-US => en_us". 11 | def locale_code 12 | locale.code.underscore.downcase 13 | end 14 | 15 | # Returns value of file_url. 16 | def file_url 17 | value_for(:file_url) 18 | end 19 | 20 | # Checks if updating objects has added any asset. 21 | def file_url? 22 | file_url.present? 23 | end 24 | 25 | # Returns value of title. 26 | def title 27 | value_for(:title) 28 | end 29 | 30 | # Returns value of file_type. 31 | def file_type 32 | value_for(:file_type) 33 | end 34 | 35 | # Returns value of file. 36 | def file 37 | value_for(:file) 38 | end 39 | 40 | # Takes name of attribute. 41 | # Returns value from params or form instance. 42 | def value_for(method) 43 | name = param_name(method) 44 | params[name].presence || object.instance_variable_get("@#{name}") 45 | end 46 | 47 | # Takes attribute name. 48 | # Returns attribute with the locale code suffix. 49 | def param_name(method) 50 | "#{method}_#{locale_code}" 51 | end 52 | end 53 | end -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | 3 | protect_from_forgery with: :exception 4 | skip_before_action :verify_authenticity_token 5 | 6 | before_action :initialize_contentful_client 7 | before_action :check_setup 8 | 9 | private 10 | 11 | def initialize_contentful_client 12 | @settings = Settings.all.first 13 | @settings.try(:initialize_contentful_client) 14 | end 15 | 16 | def check_setup 17 | redirect_to new_settings_path unless @settings 18 | end 19 | 20 | def publish_object(object) 21 | object.ct_object.publish 22 | object.ct_object.published? ? 'Successfully published!' : "Validation Error - cannot publish object with ID: #{object.id}!" 23 | end 24 | 25 | def unpublish_object(object) 26 | object.ct_object.unpublish 27 | 'Successfully unpublished!' 28 | end 29 | 30 | def delete_from_cache_while_edit(object, entity_id) 31 | APICache.delete "#{object.ct_type}_#{entity_id}" 32 | end 33 | 34 | def find_space 35 | case params[:action] 36 | when 'edit', 'update' 37 | APICache.delete('space_cache_key') 38 | @space = Contentful::Management::Space.find(@settings.space_id) 39 | else 40 | @space = APICache.get('space_cache_key', period: 0) do 41 | Contentful::Management::Space.find(@settings.space_id) 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

We're sorry, but something went wrong.

54 |
55 |

If you are the application owner check the logs for more information.

56 | 57 | 58 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

The change you wanted was rejected.

54 |

Maybe you tried to change something you didn't have access to.

55 |
56 |

If you are the application owner check the logs for more information.

57 | 58 | 59 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

The page you were looking for doesn't exist.

54 |

You may have mistyped the address or the page may have moved.

55 |
56 |

If you are the application owner check the logs for more information.

57 | 58 | 59 | -------------------------------------------------------------------------------- /app/controllers/categories_controller.rb: -------------------------------------------------------------------------------- 1 | class CategoriesController < ApplicationController 2 | 3 | before_action :find_space 4 | before_action :find_category, only: [:edit, :toggle_status, :update, :destroy] 5 | before_action :delete_from_cache, only: [:edit] 6 | 7 | def index 8 | @categories = Category.all(@space) 9 | end 10 | 11 | def new 12 | @category = Category.new({space: @space}) 13 | end 14 | 15 | def create 16 | @category = Category.new(params[:category].merge(space: @space)) 17 | if @category.save(@space) 18 | redirect_to categories_path, notice: 'Successfully created!' 19 | else 20 | redirect_to new_category_path, notice: "#{display_errors}" 21 | end 22 | end 23 | 24 | def edit 25 | end 26 | 27 | def toggle_status 28 | msg = @category.ct_object.published? ? unpublish_object(@category) : publish_object(@category) 29 | redirect_to categories_path, notice: msg 30 | end 31 | 32 | def update 33 | if @category.update(params[:category]) 34 | redirect_to categories_path, notice: 'Successfully updated!' 35 | else 36 | redirect_to edit_category_path(params[:id]), notice: "#{display_errors}" 37 | end 38 | end 39 | 40 | def destroy 41 | @category.destroy 42 | redirect_to categories_path, notice: 'Successfully deleted!' 43 | end 44 | 45 | def delete_from_cache 46 | delete_from_cache_while_edit(@category, params[:id]) 47 | end 48 | 49 | private 50 | 51 | def find_category 52 | @category = Category.find(@space, params[:id]) 53 | end 54 | 55 | def display_errors 56 | @category.errors_contentful.join(', ') 57 | end 58 | 59 | end -------------------------------------------------------------------------------- /spec/controllers/categories_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe CategoriesController do 4 | 5 | let!(:settings) { create(:settings) } 6 | render_views 7 | 8 | it 'index' do 9 | vcr('category/index') do 10 | get :index 11 | expect(response.status).to eq 200 12 | response.should render_template :index 13 | end 14 | end 15 | 16 | it 'new' do 17 | vcr('category/new') do 18 | get :new 19 | expect(response.status).to eq 200 20 | response.should render_template :new 21 | end 22 | end 23 | 24 | it 'create' do 25 | vcr('category/create') do 26 | post :create, category: {name_en_us: 'Sports EN', name_de_de: 'Sport DE', name_pl_pl: 'Sport PL', 27 | description_en_us: 'Sports category EN', description_de_de: 'Sports category EN', description_pl_pl: 'Sports category EN'} 28 | expect(response.status).to eq 302 29 | response.should redirect_to categories_path 30 | end 31 | end 32 | 33 | it 'update' do 34 | vcr('category/update') do 35 | put :update, id: '14498XWGiIwQyOAmKq2YeO', category: {name_en_us: 'Sports EN', name_de_de: 'Sport DE', name_pl_pl: 'Sport PL', 36 | description_en_us: 'Sports category EN'} 37 | expect(response.status).to eq 302 38 | response.should redirect_to categories_path 39 | end 40 | end 41 | 42 | it 'destroy' do 43 | vcr('category/destroy') do 44 | delete :destroy, id: '2TfOVAXdVYkMYuAsWsW8EW' 45 | expect(response.status).to eq 302 46 | response.should redirect_to categories_path 47 | end 48 | end 49 | 50 | end -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | CmaDemoApp::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static asset server for tests with Cache-Control for performance. 16 | config.serve_static_assets = true 17 | config.static_cache_control = "public, max-age=3600" 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Print deprecation notices to the stderr. 35 | config.active_support.deprecation = :stderr 36 | end 37 | -------------------------------------------------------------------------------- /spec/controllers/images_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe ImagesController do 4 | 5 | let!(:settings) { create(:settings) } 6 | 7 | render_views 8 | 9 | it 'index' do 10 | vcr('image/index') do 11 | get :index 12 | expect(response.status).to eq 200 13 | response.should render_template :index 14 | end 15 | end 16 | 17 | it 'new' do 18 | vcr('image/new') do 19 | get :new 20 | expect(response.status).to eq 200 21 | response.should render_template :new 22 | end 23 | end 24 | 25 | it 'create' do 26 | vcr('image/create') do 27 | post :create, 28 | image: { 29 | title_en_us: 'Test name', 30 | description_en_us: 'Test description', 31 | file_url_en_us: 'https://upload.wikimedia.org/wikipedia/commons/c/c7/Gasometer_Berlin_Sch%C3%B6neberg_2011.jpg', 32 | file_type_en_us: 'image/jpeg' 33 | } 34 | expect(response.status).to eq 302 35 | end 36 | end 37 | 38 | it 'update' do 39 | vcr('image/update') do 40 | put :update, id: '6rsv917hReaKM8CyIGSES', 41 | image: { 42 | title_en_us: 'Test name', 43 | description_en_us: 'Test description', 44 | file_url_en_us: 'https://upload.wikimedia.org/wikipedia/commons/c/c7/Gasometer_Berlin_Sch%C3%B6neberg_2011.jpg', 45 | file_type_en_us: 'image/jpeg' 46 | } 47 | expect(response.status).to eq 302 48 | end 49 | end 50 | 51 | it 'destroy' do 52 | vcr('image/destroy') do 53 | delete :destroy, id: '6rsv917hReaKM8CyIGSES' 54 | expect(response.status).to eq 302 55 | response.should redirect_to images_path 56 | end 57 | end 58 | 59 | end -------------------------------------------------------------------------------- /spec/controllers/posts_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe PostsController do 4 | 5 | let!(:settings) { create(:settings) } 6 | render_views 7 | 8 | it 'index' do 9 | vcr('post/index') do 10 | get :index 11 | expect(response.status).to eq 200 12 | response.should render_template :index 13 | end 14 | end 15 | 16 | it 'new' do 17 | vcr('post/new') do 18 | get :new 19 | expect(response.status).to eq 200 20 | response.should render_template :new 21 | end 22 | end 23 | 24 | it 'create' do 25 | vcr('post/create') do 26 | post :create, post: {title_en_us: 'Sport is good for health...', 27 | author_en_us: 'Protas', 28 | body_en_us: 'Some body', 29 | title_image_en_us_id: '4OnNiEyHiow0i2IKWUyE4u', 30 | second_image_en_us_id: '25YMjrnn2IUy2u0qUS0aCw', 31 | category_en_us: '4edQsVRm8g4UAwqGGwmcWA'} 32 | expect(response.status).to eq 302 33 | response.should redirect_to posts_path 34 | end 35 | end 36 | 37 | it 'update' do 38 | vcr('post/update') do 39 | put :update, id: '4Pd4NpuW1q4GI4qWacamIO', post: {title_en_us: 'Sports', 40 | author_en_us: 'P. Protas', 41 | body_en_us: 'body update', 42 | title_image_en_us_id: '4teeyoy7SUMgmGaiG0YiYW', 43 | second_image_en_us_id: '2clOr9mxFGUIoOm0i6UeiA'} 44 | expect(response.status).to eq 302 45 | response.should redirect_to posts_path 46 | end 47 | end 48 | 49 | it 'destroy' do 50 | vcr('post/destroy') do 51 | delete :destroy, id: '3b5W5MAuX6gYi0EquAWCas' 52 | expect(response.status).to eq 302 53 | response.should redirect_to posts_path 54 | end 55 | end 56 | 57 | end -------------------------------------------------------------------------------- /app/views/layouts/application.html.slim: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | meta charset="utf-8" 4 | meta content="IE=edge" http-equiv="X-UA-Compatible" 5 | meta content="width=device-width, initial-scale=1" name="viewport" 6 | title Contentful CMA 7 | = stylesheet_link_tag 'application', media: 'all' 8 | body 9 | .navbar.navbar-default role="navigation" 10 | .container-fluid 11 | .navbar-header 12 | = link_to 'CMA', posts_path, class: 'navbar-brand' 13 | .collapse.navbar-collapse 14 | ul.nav.navbar-nav 15 | li.dropdown 16 | = link_to posts_path, class: 'dropdown-toggle', 'data-toggle' => 'dropdown' do 17 | = 'Posts' 18 | span.caret 19 | ul.dropdown-menu role="menu" 20 | li 21 | = link_to 'List', posts_path 22 | li 23 | = link_to 'Add', new_post_path 24 | li.dropdown 25 | = link_to categories_path, class: 'dropdown-toggle', 'data-toggle' => 'dropdown' do 26 | = 'Categories' 27 | span.caret 28 | ul.dropdown-menu role="menu" 29 | li 30 | = link_to 'List', categories_path 31 | li 32 | = link_to 'Add', new_category_path 33 | li.dropdown 34 | = link_to images_path, class: 'dropdown-toggle', 'data-toggle' => 'dropdown' do 35 | = 'Images' 36 | span.caret 37 | ul.dropdown-menu role="menu" 38 | li 39 | = link_to 'List', images_path 40 | li 41 | = link_to 'Add', new_image_path 42 | li 43 | = link_to 'Settings', edit_settings_path 44 | .container 45 | .row 46 | .col-md-8 47 | - flash.each do |type, message| 48 | = content_tag(:div, class: "alert #{alert_class_for(type)}") do 49 | button.close data-dismiss="alert" 50 | 'x 51 | = message.html_safe 52 | = yield 53 | = javascript_include_tag 'application' -------------------------------------------------------------------------------- /app/models/settings.rb: -------------------------------------------------------------------------------- 1 | class Settings < ActiveRecord::Base 2 | 3 | validates :access_token, :organization_id, presence: true 4 | 5 | def setup 6 | initialize_contentful_client 7 | space = create_space(organization_id) 8 | create_locales(space) 9 | create_category_content_type(space) 10 | create_post_content_type(space) 11 | update_column(:space_id, space.id) 12 | end 13 | 14 | def initialize_contentful_client 15 | Contentful::Management::Client.new(access_token) 16 | end 17 | 18 | private 19 | 20 | def create_space(organization_id) 21 | Contentful::Management::Space.create(name: 'CMA Demo Rails App', organization_id: organization_id) 22 | end 23 | 24 | def create_locales(space) 25 | space.locales.create(name: 'English', code: 'en-US') 26 | space.locales.create(name: 'German', code: 'de-DE') 27 | end 28 | 29 | def create_category_content_type(space) 30 | category_type = space.content_types.create(id: 'category_content_type', name: 'Category') 31 | category_type.fields.create(id: 'name', name: 'Name', type: 'Text', localized: true) 32 | category_type.fields.create(id: 'description', name: 'Description', type: 'Text', localized: true) 33 | category_type.update(displayField: 'name') 34 | category_type.activate 35 | end 36 | 37 | def create_post_content_type(space) 38 | post_type = space.content_types.create(id: 'post_content_type', name: 'Post') 39 | post_type.fields.create(id: 'title', name: 'Title', type: 'Text', localized: true) 40 | post_type.fields.create(id: 'author', name: 'Author', type: 'Text', localized: true) 41 | post_type.fields.create(id: 'body', name: 'Body', type: 'Text', localized: true) 42 | post_type.fields.create(id: 'title_image', name: 'Title Image', type: 'Link', link_type: 'Asset', localized: true, required: true) 43 | post_type.fields.create(id: 'second_image', name: 'Second Image', type: 'Link', link_type: 'Asset', localized: true) 44 | post_type.fields.create(id: 'category', name: 'Category', type: 'Link', link_type: 'Entry', localized: true) 45 | 46 | post_type.update(displayField: 'title') 47 | 48 | post_type.activate 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV["RAILS_ENV"] ||= 'test' 3 | require 'simplecov' 4 | SimpleCov.start 5 | require 'spec_helper' 6 | require File.expand_path("../../config/environment", __FILE__) 7 | require 'rspec/rails' 8 | 9 | # Requires supporting ruby files with custom matchers and macros, etc, in 10 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are 11 | # run as spec files by default. This means that files in spec/support that end 12 | # in _spec.rb will both be required and run as specs, causing the specs to be 13 | # run twice. It is recommended that you do not name files matching this glob to 14 | # end with _spec.rb. You can configure this pattern with the --pattern 15 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. 16 | Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } 17 | 18 | # Checks for pending migrations before tests are run. 19 | # If you are not using ActiveRecord, you can remove this line. 20 | ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration) 21 | 22 | RSpec.configure do |config| 23 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 24 | # config.fixture_path = "#{::Rails.root}/spec/fixtures" 25 | config.include FactoryGirl::Syntax::Methods 26 | 27 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 28 | # examples within a transaction, remove the following line or assign false 29 | # instead of true. 30 | config.use_transactional_fixtures = true 31 | 32 | # RSpec Rails can automatically mix in different behaviours to your tests 33 | # based on their file location, for example enabling you to call `get` and 34 | # `post` in specs under `spec/controllers`. 35 | # 36 | # You can disable this behaviour by removing the line below, and instead 37 | # explicitly tag your specs with their type, e.g.: 38 | # 39 | # RSpec.describe UsersController, :type => :controller do 40 | # # ... 41 | # end 42 | # 43 | # The different available types are documented in the features, such as in 44 | # https://relishapp.com/rspec/rspec-rails/docs 45 | config.infer_spec_type_from_file_location! 46 | end 47 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | CmaDemoApp::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both thread web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. 20 | # config.action_dispatch.rack_cache = true 21 | 22 | # Disable Rails's static asset server (Apache or nginx will already do this). 23 | config.serve_static_assets = false 24 | 25 | # Compress JavaScripts and CSS. 26 | config.assets.js_compressor = :uglifier 27 | # config.assets.css_compressor = :sass 28 | 29 | # Do not fallback to assets pipeline if a precompiled asset is missed. 30 | config.assets.compile = false 31 | 32 | # Generate digests for assets URLs. 33 | config.assets.digest = true 34 | 35 | # Version of your assets, change this if you want to expire all your assets. 36 | config.assets.version = '1.0' 37 | 38 | # Specifies the header that your server uses for sending files. 39 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 40 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 41 | 42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 43 | # config.force_ssl = true 44 | 45 | # Set to :debug to see everything in the log. 46 | config.log_level = :info 47 | 48 | # Prepend all log lines with the following tags. 49 | # config.log_tags = [ :subdomain, :uuid ] 50 | 51 | # Use a different logger for distributed setups. 52 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 53 | 54 | # Use a different cache store in production. 55 | # config.cache_store = :mem_cache_store 56 | 57 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 58 | # config.action_controller.asset_host = "http://assets.example.com" 59 | 60 | # Precompile additional assets. 61 | # application.js, application.css.scss, and all non-JS/CSS in app/assets folder are already added. 62 | # config.assets.precompile += %w( search.js ) 63 | 64 | # Ignore bad email addresses and do not raise email delivery errors. 65 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 66 | # config.action_mailer.raise_delivery_errors = false 67 | 68 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 69 | # the I18n.default_locale when a translation can not be found). 70 | config.i18n.fallbacks = true 71 | 72 | # Send deprecation notices to registered listeners. 73 | config.active_support.deprecation = :notify 74 | 75 | # Disable automatic flushing of the log to improve performance. 76 | # config.autoflush_log = false 77 | 78 | # Use default logging formatter so that PID and timestamp are not suppressed. 79 | config.log_formatter = ::Logger::Formatter.new 80 | end 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Rails Example Application 2 | ============= 3 | 4 | ## Description ## 5 | Sample Rails app to demonstrate the content creation using the [Content Management API RubyGem](https://github.com/contentful/contentful-management.rb). 6 | 7 | ## Installation ## 8 | 9 | Clone the repository and run 10 | 11 | ``` shell 12 | bundle install 13 | ``` 14 | 15 | ## Usage ## 16 | Run the application with ```bundle exec rails server``` and open ```http://0.0.0.0:3000/``` in your browser. 17 | The first time you use the application, you will be asked to enter your Contentful ```ACCESS_TOKEN``` and ```ORGANIZATION_ID```. 18 | 19 | Once you save your credentials the app will create a space called "CMA Rails App Demo" and setup the ```Post```, ```Category``` content types 20 | 21 | Your credentials will be stored in the settings table in a locale SQLite database. 22 | 23 | 24 | ## Contentful module ## 25 | 26 | #### Entity #### 27 | Initializes objects of Entry type. 28 | Classes that operate on Contentful::Management::Entry objects inherit from it. 29 | 30 | Example 31 | ``` ruby 32 | class Category < Contentful::Entity 33 | 34 | content_type :category_content_type 35 | 36 | end 37 | ``` 38 | 39 | #### Methods #### 40 | * initialize 41 | 42 | Creates localized getters and setters based on the fields of a content type. 43 | 44 | Example: two locales with code ```en-US```, ```"de-DE" ``` and a field with API a name: ```title```. 45 | ``` ruby 46 | title_en_us 47 | title_de_de 48 | ``` 49 | 50 | * content_type 51 | 52 | Gets ID of the content type that you referring to. It helps to find a specified content type and is useful for filtering entries. 53 | 54 | * locales 55 | 56 | Returns the locales that are available for the space. 57 | 58 | * has_one 59 | 60 | To declare an association to other entries. The model defines the relationship through the name of 'API' field. 61 | 62 | For example, if the post content type has a ```Link field``` with the api_name ```category``` 63 | 64 | ``` ruby 65 | class Post < Contentful::Entity 66 | 67 | content_type :post_content_type 68 | 69 | has_one :category 70 | 71 | end 72 | ``` 73 | 74 | In the views, you an return the name of a linked Entry like this: 75 | 76 | ``` ruby 77 | = link_to post.category(@space).name 78 | ``` 79 | 80 | * all(space) 81 | 82 | This method returns all objects for your space. All created objects are cached by the [APICache](https://github.com/mloughran/api_cache) Gem. 83 | 84 | * find(space, id) 85 | 86 | Returns contentful object. Every object is cached. 87 | 88 | * build(ct_object, space) 89 | 90 | Initialize an entry object from the API. 91 | 92 | #### Asset #### 93 | 94 | This class inherits from Entity and represents the asset content type. Classes that operate on Contentful::Management::Asset objects inherit from it. 95 | 96 | 97 | ``` ruby 98 | class Image < Contentful::Asset 99 | 100 | end 101 | ``` 102 | 103 | #### Error handling #### 104 | 105 | Using ActiveModel, we have no possibility to check the type of input data. They are always treated as a String value. We used custom casting type, by checking the type of content type field. Error handling has been added to the basic actions. It checks if the passed parameter has proper type. 106 | If not, the user will receive an Error object including error message. 107 | 108 | 109 | ## Helpers ## 110 | 111 | #### contentful_form_for #### 112 | 113 | Generates forms to create and edit entries and assets. It generates only fields that are localized. 114 | 115 | #### published_object(object) #### 116 | Checks status of an entry object. 117 | 118 | #### get_image #### 119 | Display the image of a linked asset. You can specify parameters, which will return a resized version the image. 120 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file was generated by the `rails generate rspec:install` command. Conventionally, all 2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 3 | # The generated `.rspec` file contains `--require spec_helper` which will cause this 4 | # file to always be loaded, without a need to explicitly require it in any files. 5 | # 6 | # Given that it is always loaded, you are encouraged to keep this file as 7 | # light-weight as possible. Requiring heavyweight dependencies from this file 8 | # will add to the boot time of your test suite on EVERY test run, even for an 9 | # individual file that may not need all of that loaded. Instead, make a 10 | # separate helper file that requires this one and then use it only in the specs 11 | # that actually need it. 12 | # 13 | # The `.rspec` file also contains a few flags that are not defaults but that 14 | # users commonly want. 15 | # 16 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 17 | RSpec.configure do |config| 18 | # The settings below are suggested to provide a good initial experience 19 | # with RSpec, but feel free to customize to your heart's content. 20 | begin 21 | # These two settings work together to allow you to limit a spec run 22 | # to individual examples or groups you care about by tagging them with 23 | # `:focus` metadata. When nothing is tagged with `:focus`, all examples 24 | # get run. 25 | config.filter_run :focus 26 | config.run_all_when_everything_filtered = true 27 | 28 | # Many RSpec users commonly either run the entire suite or an individual 29 | # file, and it's useful to allow more verbose output when running an 30 | # individual spec file. 31 | if config.files_to_run.one? 32 | # Use the documentation formatter for detailed output, 33 | # unless a formatter has already been configured 34 | # (e.g. via a command-line flag). 35 | config.default_formatter = 'doc' 36 | end 37 | 38 | # Print the 10 slowest examples and example groups at the 39 | # end of the spec run, to help surface which specs are running 40 | # particularly slow. 41 | config.profile_examples = 10 42 | 43 | # Run specs in random order to surface order dependencies. If you find an 44 | # order dependency and want to debug it, you can fix the order by providing 45 | # the seed, which is printed after each run. 46 | # --seed 1234 47 | config.order = :random 48 | 49 | # Seed global randomization in this process using the `--seed` CLI option. 50 | # Setting this allows you to use `--seed` to deterministically reproduce 51 | # test failures related to randomization by passing the same `--seed` value 52 | # as the one that triggered the failure. 53 | Kernel.srand config.seed 54 | 55 | # rspec-expectations config goes here. You can use an alternate 56 | # assertion/expectation library such as wrong or the stdlib/minitest 57 | # assertions if you prefer. 58 | config.expect_with :rspec do |expectations| 59 | # Enable only the newer, non-monkey-patching expect syntax. 60 | # For more details, see: 61 | # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax 62 | expectations.syntax = [:should, :expect] 63 | end 64 | 65 | # rspec-mocks config goes here. You can use an alternate test double 66 | # library (such as bogus or mocha) by changing the `mock_with` option here. 67 | config.mock_with :rspec do |mocks| 68 | # Enable only the newer, non-monkey-patching expect syntax. 69 | # For more details, see: 70 | # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ 71 | mocks.syntax = :expect 72 | 73 | # Prevents you from mocking or stubbing a method that does not exist on 74 | # a real object. This is generally recommended. 75 | mocks.verify_partial_doubles = true 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /app/controllers/posts_controller.rb: -------------------------------------------------------------------------------- 1 | class PostsController < ApplicationController 2 | 3 | before_action :find_space 4 | before_action :find_post, only: [:edit, :show, :update, :toggle_status, :destroy] 5 | before_action :find_related_objects, only: [:new, :edit, :show] 6 | before_action :delete_from_cache, only: [:edit] 7 | 8 | def index 9 | @posts = Post.all(@space) 10 | end 11 | 12 | def new 13 | @post = Post.new({space: @space}) 14 | end 15 | 16 | def show 17 | end 18 | 19 | def create 20 | post = Post.new(post_params.merge({space: @space})) 21 | post.save(@space) 22 | redirect_to posts_path 23 | end 24 | 25 | def edit 26 | 27 | end 28 | 29 | def toggle_status 30 | msg = @post.ct_object.published? ? unpublish_object(@post) : publish_object(@post) 31 | redirect_to posts_path, notice: msg 32 | end 33 | 34 | def update 35 | if @post.update(post_params) 36 | redirect_to posts_path, notice: 'Successfully updated!' 37 | else 38 | redirect_to edit_category_path(params[:id]), notice: "#{display_errors(@post)}" 39 | end 40 | end 41 | 42 | def destroy 43 | @post.destroy 44 | redirect_to posts_path, notice: 'Successfully deleted!' 45 | end 46 | 47 | private 48 | 49 | def delete_from_cache 50 | delete_from_cache_while_edit(@post, params[:id]) 51 | end 52 | 53 | def find_post 54 | @post = Post.find(@space, params[:id]) 55 | end 56 | 57 | def post_params 58 | find_categories 59 | find_images 60 | params[:post] 61 | end 62 | 63 | def find_images 64 | title_en_id = params[:post].delete(:title_image_en_us_id) 65 | title_en = title_en_id.present? ? Image.find(@space, title_en_id).ct_object : nil 66 | params[:post].merge!(title_image_en_us_id: title_en) if title_en 67 | title_de_id = params[:post].delete(:title_image_de_de_id) 68 | title_de = title_de_id.present? ? Image.find(@space, title_de_id).ct_object : nil 69 | params[:post].merge!(title_image_de_de_id: title_de) if title_de 70 | title_pl_id = params[:post].delete(:title_image_pl_pl_id) 71 | title_pl = title_pl_id.present? ? Image.find(@space, title_pl_id).ct_object : nil 72 | params[:post].merge!(title_image_pl_pl_id: title_pl) if title_pl 73 | 74 | second_title_en_id = params[:post].delete(:second_image_en_us_id) 75 | second_title_en = second_title_en_id.present? ? Image.find(@space, second_title_en_id).ct_object : nil 76 | params[:post].merge!(second_image_en_us_id: second_title_en) if second_title_en 77 | second_title_de_id = params[:post].delete(:second_image_de_de_id) 78 | second_title_de = second_title_de_id.present? ? Image.find(@space, second_title_de_id).ct_object : nil 79 | params[:post].merge!(second_image_de_de_id: second_title_de) if second_title_de 80 | second_title_pl_id = params[:post].delete(:second_image_pl_pl_id) 81 | second_title_pl = second_title_pl_id.present? ? Image.find(@space, second_title_pl_id).ct_object : nil 82 | params[:post].merge!(second_image_pl_pl_ix: second_title_pl) if second_title_pl 83 | end 84 | 85 | def find_categories 86 | category_en_id = params[:post].delete(:category_en_us_id) 87 | category_en = category_en_id.present? ? Category.find(@space, category_en_id).ct_object : nil 88 | params[:post].merge!(category_en_us_id: category_en) if category_en 89 | category_de_id = params[:post].delete(:category_de_de_id) 90 | category_de = category_de_id.present? ? Category.find(@space, category_de_id).ct_object : nil 91 | params[:post].merge!(category_de_de_id: category_de) if category_de 92 | category_pl_id = params[:post].delete(:category_pl_pl_id) 93 | category_pl = category_pl_id.present? ? Category.find(@space, category_pl_id).ct_object : nil 94 | params[:post].merge!(category_pl_pl_id: category_pl) if category_pl 95 | end 96 | 97 | def find_related_objects 98 | @images = Image.all(@space) 99 | @categories = Category.all(@space) 100 | end 101 | 102 | def display_errors 103 | @post.errors_contentful.join(', ') 104 | end 105 | 106 | end -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: /Users/piotrprotas/Documents/RUBY_CONTENTUL/contentful-management.rb 3 | specs: 4 | contentful-management (0.6.0) 5 | http (~> 0.6) 6 | multi_json (~> 1) 7 | 8 | GEM 9 | remote: https://rubygems.org/ 10 | specs: 11 | actionmailer (4.0.3) 12 | actionpack (= 4.0.3) 13 | mail (~> 2.5.4) 14 | actionpack (4.0.3) 15 | activesupport (= 4.0.3) 16 | builder (~> 3.1.0) 17 | erubis (~> 2.7.0) 18 | rack (~> 1.5.2) 19 | rack-test (~> 0.6.2) 20 | activemodel (4.0.3) 21 | activesupport (= 4.0.3) 22 | builder (~> 3.1.0) 23 | activerecord (4.0.3) 24 | activemodel (= 4.0.3) 25 | activerecord-deprecated_finders (~> 1.0.2) 26 | activesupport (= 4.0.3) 27 | arel (~> 4.0.0) 28 | activerecord-deprecated_finders (1.0.3) 29 | activesupport (4.0.3) 30 | i18n (~> 0.6, >= 0.6.4) 31 | minitest (~> 4.2) 32 | multi_json (~> 1.3) 33 | thread_safe (~> 0.1) 34 | tzinfo (~> 0.3.37) 35 | addressable (2.3.6) 36 | api_cache (0.3.0) 37 | arel (4.0.2) 38 | bootstrap-sass (3.2.0.2) 39 | sass (~> 3.2) 40 | builder (3.1.4) 41 | coffee-rails (4.0.1) 42 | coffee-script (>= 2.2.0) 43 | railties (>= 4.0.0, < 5.0) 44 | coffee-script (2.3.0) 45 | coffee-script-source 46 | execjs 47 | coffee-script-source (1.8.0) 48 | crack (0.4.2) 49 | safe_yaml (~> 1.0.0) 50 | daemons (1.1.9) 51 | diff-lcs (1.2.5) 52 | docile (1.1.5) 53 | erubis (2.7.0) 54 | eventmachine (1.0.4) 55 | execjs (2.2.2) 56 | factory_girl (4.4.0) 57 | activesupport (>= 3.0.0) 58 | factory_girl_rails (4.4.1) 59 | factory_girl (~> 4.4.0) 60 | railties (>= 3.0.0) 61 | form_data (0.1.0) 62 | hike (1.2.3) 63 | http (0.7.1) 64 | form_data (~> 0.1.0) 65 | http_parser.rb (~> 0.6.0) 66 | http_parser.rb (0.6.0) 67 | i18n (0.7.0) 68 | jbuilder (1.5.3) 69 | activesupport (>= 3.0.0) 70 | multi_json (>= 1.2.0) 71 | jquery-rails (3.1.2) 72 | railties (>= 3.0, < 5.0) 73 | thor (>= 0.14, < 2.0) 74 | json (1.8.2) 75 | mail (2.5.4) 76 | mime-types (~> 1.16) 77 | treetop (~> 1.4.8) 78 | mime-types (1.25.1) 79 | minitest (4.7.5) 80 | multi_json (1.10.1) 81 | polyglot (0.3.5) 82 | rack (1.5.2) 83 | rack-test (0.6.3) 84 | rack (>= 1.0) 85 | rails (4.0.3) 86 | actionmailer (= 4.0.3) 87 | actionpack (= 4.0.3) 88 | activerecord (= 4.0.3) 89 | activesupport (= 4.0.3) 90 | bundler (>= 1.3.0, < 2.0) 91 | railties (= 4.0.3) 92 | sprockets-rails (~> 2.0.0) 93 | railties (4.0.3) 94 | actionpack (= 4.0.3) 95 | activesupport (= 4.0.3) 96 | rake (>= 0.8.7) 97 | thor (>= 0.18.1, < 2.0) 98 | rake (10.4.2) 99 | rdoc (4.2.0) 100 | json (~> 1.4) 101 | rspec-core (3.0.4) 102 | rspec-support (~> 3.0.0) 103 | rspec-expectations (3.0.4) 104 | diff-lcs (>= 1.2.0, < 2.0) 105 | rspec-support (~> 3.0.0) 106 | rspec-mocks (3.0.4) 107 | rspec-support (~> 3.0.0) 108 | rspec-rails (3.0.2) 109 | actionpack (>= 3.0) 110 | activesupport (>= 3.0) 111 | railties (>= 3.0) 112 | rspec-core (~> 3.0.0) 113 | rspec-expectations (~> 3.0.0) 114 | rspec-mocks (~> 3.0.0) 115 | rspec-support (~> 3.0.0) 116 | rspec-support (3.0.4) 117 | safe_yaml (1.0.4) 118 | sass (3.2.19) 119 | sass-rails (4.0.5) 120 | railties (>= 4.0.0, < 5.0) 121 | sass (~> 3.2.2) 122 | sprockets (~> 2.8, < 3.0) 123 | sprockets-rails (~> 2.0) 124 | sdoc (0.4.1) 125 | json (~> 1.7, >= 1.7.7) 126 | rdoc (~> 4.0) 127 | shoulda (3.5.0) 128 | shoulda-context (~> 1.0, >= 1.0.1) 129 | shoulda-matchers (>= 1.4.1, < 3.0) 130 | shoulda-context (1.2.1) 131 | shoulda-matchers (2.7.0) 132 | activesupport (>= 3.0.0) 133 | simplecov (0.9.1) 134 | docile (~> 1.1.0) 135 | multi_json (~> 1.0) 136 | simplecov-html (~> 0.8.0) 137 | simplecov-html (0.8.0) 138 | slim (2.1.0) 139 | temple (~> 0.6.9) 140 | tilt (>= 1.3.3, < 2.1) 141 | slim-rails (2.1.5) 142 | actionpack (>= 3.0, < 4.2) 143 | activesupport (>= 3.0, < 4.2) 144 | railties (>= 3.0, < 4.2) 145 | slim (~> 2.0) 146 | sprockets (2.12.3) 147 | hike (~> 1.2) 148 | multi_json (~> 1.0) 149 | rack (~> 1.0) 150 | tilt (~> 1.1, != 1.3.0) 151 | sprockets-rails (2.0.1) 152 | actionpack (>= 3.0) 153 | activesupport (>= 3.0) 154 | sprockets (~> 2.8) 155 | sqlite3 (1.3.10) 156 | temple (0.6.10) 157 | thin (1.6.3) 158 | daemons (~> 1.0, >= 1.0.9) 159 | eventmachine (~> 1.0) 160 | rack (~> 1.0) 161 | thor (0.19.1) 162 | thread_safe (0.3.4) 163 | tilt (1.4.1) 164 | treetop (1.4.15) 165 | polyglot 166 | polyglot (>= 0.3.1) 167 | tzinfo (0.3.42) 168 | uglifier (2.7.0) 169 | execjs (>= 0.3.0) 170 | json (>= 1.8.0) 171 | vcr (2.9.3) 172 | webmock (1.20.4) 173 | addressable (>= 2.3.6) 174 | crack (>= 0.3.2) 175 | 176 | PLATFORMS 177 | ruby 178 | 179 | DEPENDENCIES 180 | api_cache 181 | bootstrap-sass (~> 3.2.0) 182 | coffee-rails (~> 4.0.0) 183 | contentful-management! 184 | factory_girl_rails (= 4.4.1) 185 | jbuilder (~> 1.2) 186 | jquery-rails 187 | rails (= 4.0.3) 188 | rspec-rails (~> 3.0.0) 189 | sass-rails (~> 4.0.1) 190 | sdoc 191 | shoulda (= 3.5.0) 192 | simplecov 193 | slim-rails (= 2.1.5) 194 | sqlite3 195 | thin 196 | uglifier (>= 1.3.0) 197 | vcr 198 | webmock 199 | -------------------------------------------------------------------------------- /app/models/contentful/asset.rb: -------------------------------------------------------------------------------- 1 | module Contentful 2 | # Resource class for Contentful Asset objects. 3 | class Asset < Contentful::Entity 4 | ATTRIBUTES = [:title, :description, :file_url, :file_type, :file] 5 | CONTENTFUL_FIELDS = [:title, :description, :file] 6 | 7 | attr_accessor *ATTRIBUTES 8 | 9 | delegate :image_url, to: :ct_object 10 | 11 | # Create accessors to Asset. 12 | # Takes attributes of ContentType and space. 13 | # Returns localised accessors for Contentful Asset 14 | # Example: If space has 2 locales (code: 'en-US', 'de-DE'), accessors 'title_en_us, title_de_de' will be created. 15 | def initialize(params) 16 | @errors_contentful = [] 17 | @space = params.delete(:space) 18 | setup_localised_attributes(ATTRIBUTES, params) 19 | end 20 | 21 | # Saves the model and Contentful Asset object. 22 | # Takes attributes of Asset and space. 23 | # Returns localised accessors for Contentful Asset 24 | def save(space) 25 | if ct_object 26 | update(params_from_instance_variables) 27 | else 28 | ct_object = create(space) 29 | end 30 | object = self.class.new(ct_object.fields.merge(space: space)) 31 | object.send(:assign_data, ct_object, space) 32 | end 33 | 34 | # Create the Contentful Asset object. 35 | # Takes a space and attributes from instance variables. 36 | # Returns an asset and process file. 37 | def create(space) 38 | asset = space.assets.new 39 | set_files_instance_variables 40 | assign_parameters_for(asset) 41 | asset.save 42 | asset.process_file 43 | end 44 | 45 | # Updates an asset. 46 | # Takes hash with attributes (title, description, file). 47 | # Transform hash with localised file attributes and build File object. 48 | # Return model object. 49 | def update(params) 50 | transform_file_parameters(params) 51 | assign_parameters_for_fields(CONTENTFUL_FIELDS, params) 52 | assign_attributes_from(params) 53 | ct_object = self.ct_object.save 54 | object = assign_data(ct_object, space) 55 | ct_object.process_file 56 | APICache.delete(object.cache_key) 57 | rescue 58 | errors_contentful << ct_object.error[:details] 59 | valid_asset? 60 | end 61 | 62 | # Assigns parameters to asset field. 63 | # Takes field and hash with parameters. 64 | def assign_parameters_for_field(field, params) 65 | field_params = locales.each_with_object({}) do |locale, field_params| 66 | field_name = localized_field_name(field, locale) 67 | params.each do |name, value| 68 | field_params[locale.code] = value if respond_to?(field_name) && field_name == name 69 | end 70 | end 71 | self.ct_object.send("#{field}_with_locales=", field_params) 72 | end 73 | 74 | # Creates localised form fields used in new and edit forms. 75 | def form_field_names 76 | ATTRIBUTES.each_with_object([]) do |field, fields| 77 | locales.each do |locale| 78 | fields << "#{field.downcase}_#{locale.code.underscore.downcase}" 79 | end 80 | end 81 | end 82 | 83 | # Returns localised image in views. 84 | def form_image_url(params) 85 | field_name = params.delete(:field) 86 | locale_part = field_name.gsub('file_', '') 87 | locale = locales.select { |locale| locale.code.underscore.downcase == locale_part }.first 88 | self.ct_object.locale = locale.code 89 | self.ct_object.file.present? ? self.ct_object.try(:image_url, params) : nil 90 | end 91 | 92 | class << self 93 | 94 | # Gets a collection of assets. 95 | # Takes space object. 96 | # Returns a Contentful::Management::Array of Contentful::Management::Asset. 97 | def items(space) 98 | space.assets.all 99 | end 100 | 101 | # Gets a specific asset. 102 | # Takesspace and id asset. 103 | # Returns a Contentful::Management::Asset. 104 | def item(space, id) 105 | space.assets.find(id) 106 | end 107 | 108 | end 109 | 110 | private 111 | 112 | # Create localised File object and removes not needed parameters to create Asset. 113 | def transform_file_parameters(params) 114 | locales.each do |locale| 115 | locale = FileWithLocale.new(self, locale, params) 116 | 117 | params.merge!(locale.param_name(:file) => build_file(locale)) if locale.file_url? 118 | 119 | params.delete(locale.param_name(:file_type)) 120 | params.delete(locale.param_name(:file_url)) 121 | end 122 | end 123 | 124 | # Set localised file instance variable 125 | def set_files_instance_variables 126 | locales.each do |locale| 127 | locale = FileWithLocale.new(self, locale, {}) 128 | instance_variable_set("@#{locale.param_name(:file)}", build_file(locale)) 129 | end 130 | end 131 | 132 | # Takes field and locale 133 | # Returns field with the locale code suffix, e.g name_en_us. 134 | def localized_field_name(field, locale) 135 | "#{field.to_s}_#{locale.code.underscore.downcase}" 136 | end 137 | 138 | # Build localised File object, needed to create / update an Asset. 139 | def build_file(locale = nil) 140 | file = Contentful::Management::File.new 141 | file.properties[:contentType] = locale.file_type 142 | file.properties[:fileName] = locale.title 143 | file.properties[:upload] = locale.file_url 144 | file 145 | end 146 | 147 | # Set localised instance variable based on Contentful Asset attributes. 148 | def set_instance_variable(field_name, locale, params, field) 149 | instance_variable_set("@#{field_name}", params[locale.code] ? params[locale.code][field] : params[field_name]) 150 | end 151 | 152 | def setup_attributes_for_field_and_locale(field, locale, params) 153 | setup_attributes_for_field(field, locale, params) 154 | end 155 | 156 | # Assign parameters to each asset field. 157 | def assign_parameters_for(asset) 158 | CONTENTFUL_FIELDS.each do |field| 159 | field_params = locales.each_with_object({}) do |locale, field_params| 160 | field_name = localized_field_name(field, locale) 161 | field_params[locale.code] = send(field_name) if respond_to? field_name 162 | end 163 | asset.send("#{field}_with_locales=", field_params) 164 | end 165 | end 166 | 167 | def valid_asset? 168 | errors_contentful.empty? 169 | end 170 | end 171 | end -------------------------------------------------------------------------------- /app/models/contentful/entity.rb: -------------------------------------------------------------------------------- 1 | module Contentful 2 | class Entity 3 | 4 | include ActiveModel::Model 5 | include ActiveModel::Conversion 6 | extend ActiveModel::Naming 7 | 8 | attr_accessor :ct_object, :content_type, :locales, :space, :errors_contentful 9 | 10 | # Creates accessors to Entry. 11 | # Takes attributes of ContentType and space. 12 | # Returns localised accessors for Contentful Entry. 13 | # Example: If space has 2 locales (code: 'en-US', 'de-DE'), accessors 'name_en_us, name_de_de' will be created. 14 | def initialize(params) 15 | @errors_contentful = [] 16 | @space = params.delete(:space) 17 | setup_localised_attributes(content_type.fields, params) 18 | end 19 | 20 | # Get specified content type from Contentful. 21 | # Returns Contentful Content type object. 22 | def content_type 23 | @content_type = APICache.get("content_type_#{ct_type}", period: 0) do 24 | space.content_types.find(ct_type) 25 | end 26 | end 27 | 28 | #Get all locales from Contentful Space. 29 | def locales 30 | @locales = APICache.get('locales', period: 0) do 31 | space.locales.all 32 | end 33 | end 34 | 35 | # Saves the model and Contentful Entry object. 36 | # Takes attributes of Entry and space. 37 | # Returns localised accessors for Contentful Entry 38 | def save(space) 39 | if ct_object 40 | update(params_from_instance_variables) 41 | else 42 | ct_object = create(space) 43 | end 44 | object = self.class.new(ct_object.fields.merge(space: space)) 45 | object.send(:assign_data, ct_object, space) 46 | rescue 47 | errors_contentful << ct_object.error[:details] 48 | entity_valid? 49 | end 50 | 51 | # Create the Contentful Entry object. 52 | # Takes a space and attributes from instance variables. 53 | # Returns an entry. 54 | def create(space) 55 | entry = content_type.entries.new 56 | set_localised_fields_for(entry, content_type) 57 | entry.save 58 | end 59 | 60 | # Updates an entry. 61 | # Takes hash with attributes. 62 | # Transform hash with localised file attributes and build File object. 63 | # Return model object. 64 | def update(params) 65 | assign_parameters_for_fields(content_type.fields, params) 66 | assign_attributes_from(params) 67 | ct_object = self.ct_object.save 68 | object = assign_data(ct_object, space) 69 | delete_from_cache(object.cache_key) 70 | entity_valid? 71 | end 72 | 73 | # Checks which Contentful type objects is. 74 | # Returns type and id of Contentful object. 75 | def cache_key 76 | "#{try(:ct_type) || 'asset'}_#{id}" 77 | end 78 | 79 | # Destroys an entry. 80 | def destroy 81 | ct_object.destroy 82 | end 83 | 84 | # Returns contentful ID of object. 85 | def id 86 | ct_object.try(:id) 87 | end 88 | 89 | # Creates localised form fields used in new and edit forms. 90 | def form_field_names 91 | content_type.fields.each_with_object({}) do |(field, name), fields| 92 | locales.each do |locale| 93 | fields["#{field.name.downcase}_#{locale.code.underscore.downcase}"]= field.type if field_is_localised?(field, locale) 94 | end 95 | end 96 | end 97 | 98 | # Checks if field is localised 99 | def field_is_localised?(field, locale) 100 | space.default_locale == locale.code || field.localized 101 | end 102 | 103 | class << self 104 | 105 | # Build a collection of entries from Contentful. 106 | # Takes space object. 107 | def all(space) 108 | items(space).map { |ct_object| build(ct_object, space) } 109 | end 110 | 111 | # Gets an entry from Contentful. 112 | # Takes space and entry id. 113 | # Returns always valid build model, based on Contentful attributes. 114 | def find(space, id) 115 | entity = APICache.get("#{self.try(:ct_type).to_s || 'asset'}_#{id}", period: 0, cache: 200) do 116 | build(item(space, id), space) 117 | end 118 | return_valid_entity(space, entity, id) 119 | end 120 | 121 | #Checks if entity is valid, if not fetch new one from Contentful. 122 | def return_valid_entity(space, entity, id) 123 | entity.ct_object.is_a?(Contentful::Management::Entry) || entity.ct_object.is_a?(Contentful::Management::Asset) ? entity : build(item(space, id), space) 124 | end 125 | 126 | # Gets a collection of entries. 127 | # Takes an space object. 128 | # Returns a Contentful::Management::Array of Contentful::Management::Entry. 129 | def items(space) 130 | space.entries.all(content_type: ct_type) 131 | end 132 | 133 | # Gets a specific entry. 134 | # Takes an id of entry and space object. 135 | # Returns a Contentful::Management::Entry. 136 | def item(space, id) 137 | space.entries.find(id) 138 | end 139 | 140 | # Takes content type ID. 141 | # Returns symbolised ID of Contentful content type. 142 | def content_type(content_type) 143 | define_singleton_method(:ct_type) do 144 | content_type.to_sym 145 | end 146 | define_method(:ct_type) do 147 | content_type.to_sym 148 | end 149 | end 150 | 151 | # Build and cache object based on Contentful object attributes 152 | # Takes Contentful object and space. 153 | # Returns build model object. 154 | def build(ct_object, space) 155 | object = self.new((ct_object.try(:instance_variable_get, :@fields) || {}).merge(space: space, auto: true)) 156 | object = object.send(:assign_data, ct_object, space) 157 | APICache.store.set(object.cache_key, object) if ct_object.is_a? Contentful::Management::Entry 158 | object 159 | end 160 | end 161 | 162 | private 163 | 164 | def self.has_one(attribute) 165 | define_method("#{attribute}") do |space| 166 | locale_code = space.default_locale 167 | ct_object_id = instance_variable_get("@#{attribute}_#{locale_code.underscore.downcase}_id") 168 | link = @ct_object.instance_variable_get(:@fields)[locale_code][attribute] 169 | unless ct_object_id.nil? 170 | case link['sys']['linkType'] 171 | when 'Entry' 172 | APICache.get("entry_#{link['sys']['id']}", period: 0) do 173 | space.entries.find(link['sys']['id']) 174 | end 175 | when 'Asset' 176 | APICache.get("asset_#{link['sys']['id']}", period: 0) do 177 | space.assets.find(link['sys']['id']) 178 | end 179 | end 180 | end 181 | end 182 | end 183 | 184 | def assign_data(ct_object, space = nil) 185 | self.ct_object = ct_object 186 | self.space = space if space 187 | self 188 | end 189 | 190 | def set_localised_fields_for(entry, content_type) 191 | content_type.fields.each do |field| 192 | entry.send("#{field.id}_with_locales=", create_localised_params_for(field)) 193 | end 194 | end 195 | 196 | # Assigns parameters to entry field. 197 | # Takes field from based content type. 198 | def create_localised_params_for(field) 199 | locales.each_with_object({}) do |locale, field_params| 200 | field_name = localized_field_name(field, locale) 201 | field_value = send(field_name) if respond_to? field_name 202 | field_value = nil if field_value.blank? 203 | field_params[locale.code] = cast_value_type(field, field_value) 204 | end 205 | end 206 | 207 | # Create localized fields name. 208 | # Takes content type field and locale. 209 | def localized_field_name(field, locale) 210 | name = "#{field.id}_#{locale.code.underscore.downcase}" 211 | name += '_id' if field.link_type.in?(['Entry', 'Asset']) 212 | name 213 | end 214 | 215 | def delete_from_cache(key) 216 | APICache.delete(key) 217 | end 218 | 219 | def setup_localised_attributes(fields, params) 220 | fields.each do |field| 221 | setup_localised_attributes_for_field(field, params) 222 | end 223 | end 224 | 225 | def setup_localised_attributes_for_field(field, params) 226 | locales.each do |locale| 227 | setup_attributes_for_field_and_locale(field, locale, params) 228 | end 229 | end 230 | 231 | def setup_attributes_for_field_and_locale(field, locale, params) 232 | setup_attributes_for_field(field, locale, params) if space.default_locale == locale.code || field.localized 233 | end 234 | 235 | def setup_attributes_for_field(field, locale, params) 236 | field_name = localized_field_name(field, locale) 237 | define_accessors(field_name) 238 | set_instance_variable(field_name, locale, params, field) 239 | end 240 | 241 | def set_instance_variable(field_name, locale, params, field = nil) 242 | auto_flag = params.delete(:auto) 243 | value = if field.link_type.in?(['Entry', 'Asset']) 244 | if params.present? 245 | auto_flag ? extract_value_from_ct_object(field_name, locale, params, field) : extract_value_from_form(field_name, locale, params, field) 246 | end 247 | else 248 | params[locale.code] ? params[locale.code][field.id.to_sym] : params[field_name] 249 | end 250 | instance_variable_set("@#{field_name}", value) 251 | end 252 | 253 | def extract_value_from_ct_object(field_name, locale, params, field) 254 | params[field_name].presence || params[locale.code][field.id.to_sym].present? ? params[locale.code][field.id.to_sym]['sys']['id'] : params[field_name] 255 | end 256 | 257 | def extract_value_from_form(field_name, locale, params, field) 258 | if params[locale.code].present? 259 | params[locale.code][field.id.to_sym]['sys']['id'] if params[locale.code][field.id.to_sym].present? 260 | else 261 | params[field_name] 262 | end 263 | end 264 | 265 | # Define attributes accessor based on Contentful objects attributes. 266 | def define_accessors(field_name) 267 | define_singleton_method "#{field_name}=" do |value| 268 | instance_variable_set("@#{field_name}", value) 269 | end 270 | define_singleton_method field_name do 271 | instance_variable_get("@#{field_name}") 272 | end 273 | end 274 | 275 | def assign_parameters_for_fields(fields, params) 276 | fields.each do |field| 277 | assign_parameters_for_field(field, params) 278 | end 279 | end 280 | 281 | def assign_parameters_for_field(field, params) 282 | field_params = locales.each_with_object({}) do |locale, field_params| 283 | field_name = localized_field_name(field, locale) 284 | params.each do |name, value| 285 | assign_parameter_to_field(field, field_params, locale, value) if valid_field?(field_name, name) 286 | end 287 | end 288 | self.ct_object.send("#{field.id}_with_locales=", field_params) 289 | # rescue 290 | # errors_contentful << self.ct_object.error[:details] 291 | end 292 | 293 | def assign_parameter_to_field(field, field_params, locale, value) 294 | parsed_value = cast_value_type(field, value) 295 | parsed_value = nil if parsed_value.blank? 296 | field_params[locale.code] = parsed_value 297 | end 298 | 299 | def valid_field?(field_name, name) 300 | respond_to?(field_name) && field_name == name 301 | end 302 | 303 | def assign_attributes_from(params) 304 | params.each do |name, value| 305 | self.public_send("#{name}=", value) 306 | end 307 | end 308 | 309 | def params_from_instance_variables 310 | instance_variables.each_with_object({}) do |name, params| 311 | params[name.to_s.gsub('@', '').to_sym] = instance_variable_get(name) if instance_variable_get(name).present? 312 | end 313 | end 314 | 315 | def cast_value_type(field, value) 316 | case field.type 317 | when 'Integer' 318 | is_integer?(field, value) 319 | when 'Number' 320 | is_number?(field, value) 321 | when 'Boolean' 322 | value == '1' ? true : false 323 | else 324 | value 325 | end 326 | end 327 | 328 | def is_integer?(field, value) 329 | value.to_s.match(/\A[+-]?\d+?\Z/) == nil ? add_error_message(value, error_message(field, value)) : value.to_i 330 | end 331 | 332 | def is_number?(field, value) 333 | value.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? add_error_message(value, error_message(field, value)) : value.to_f 334 | end 335 | 336 | def error_message(field, value) 337 | "You have entered the incorrect value: #{value} for the #{field.name} field. #{field.type} value required!" 338 | end 339 | 340 | def add_error_message(value, msg) 341 | value.present? ? errors_contentful << msg : nil 342 | end 343 | 344 | def entity_valid? 345 | errors_contentful.empty? 346 | end 347 | 348 | end 349 | end -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/image/new.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.contentful.com/spaces/v2umtz8ths9v 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - RubyContenfulManagementGem/0.1.0 12 | Authorization: 13 | - Bearer 14 | Content-Type: 15 | - application/vnd.contentful.management.v1+json 16 | Content-Length: 17 | - '0' 18 | Host: 19 | - api.contentful.com 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | "^access-Control-Expose-Headers": 26 | - Etag 27 | Accept-Ranges: 28 | - bytes 29 | Access-Control-Allow-Headers: 30 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 31 | Access-Control-Allow-Methods: 32 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 33 | Access-Control-Allow-Origin: 34 | - "*" 35 | Access-Control-Max-Age: 36 | - '1728000' 37 | Cache-Control: 38 | - max-age=0 39 | Content-Type: 40 | - application/vnd.contentful.management.v1+json 41 | Date: 42 | - Fri, 05 Sep 2014 12:15:28 GMT 43 | Etag: 44 | - '"35407b8a88882fe5717a4701910f6ce7"' 45 | Server: 46 | - nginx 47 | Status: 48 | - 200 OK 49 | X-Contentful-Request-Id: 50 | - f1c-1376769638 51 | Content-Length: 52 | - '459' 53 | Connection: 54 | - keep-alive 55 | body: 56 | encoding: UTF-8 57 | string: | 58 | { 59 | "sys":{ 60 | "type":"Space", 61 | "id":"v2umtz8ths9v", 62 | "version":1, 63 | "createdBy":{ 64 | "sys":{ 65 | "type":"Link", 66 | "linkType":"User", 67 | "id":"1E7acJL8I5XUXAMHQt9Grs" 68 | } 69 | }, 70 | "createdAt":"2014-08-21T13:32:11Z", 71 | "updatedBy":{ 72 | "sys":{ 73 | "type":"Link", 74 | "linkType":"User", 75 | "id":"1E7acJL8I5XUXAMHQt9Grs" 76 | } 77 | }, 78 | "updatedAt":"2014-08-21T13:32:12Z" 79 | }, 80 | "name":"CMA Demo Rails App"} 81 | http_version: 82 | recorded_at: Fri, 05 Sep 2014 12:15:59 GMT 83 | - request: 84 | method: get 85 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types 86 | body: 87 | encoding: US-ASCII 88 | string: '' 89 | headers: 90 | User-Agent: 91 | - RubyContenfulManagementGem/0.1.0 92 | Authorization: 93 | - Bearer 94 | Content-Type: 95 | - application/vnd.contentful.management.v1+json 96 | Content-Length: 97 | - '0' 98 | Host: 99 | - api.contentful.com 100 | response: 101 | status: 102 | code: 200 103 | message: OK 104 | headers: 105 | "^access-Control-Expose-Headers": 106 | - Etag 107 | Access-Control-Allow-Headers: 108 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 109 | Access-Control-Allow-Methods: 110 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 111 | Access-Control-Allow-Origin: 112 | - "*" 113 | Access-Control-Max-Age: 114 | - '1728000' 115 | Cf-Space-Id: 116 | - v2umtz8ths9v 117 | Content-Type: 118 | - application/vnd.contentful.management.v1+json 119 | Date: 120 | - Fri, 05 Sep 2014 12:15:28 GMT 121 | Etag: 122 | - '"2a8abfd957b4ad9b6b47f853bd58078a"' 123 | Server: 124 | - nginx 125 | X-Powered-By: 126 | - Express 127 | Content-Length: 128 | - '5193' 129 | Connection: 130 | - keep-alive 131 | body: 132 | encoding: UTF-8 133 | string: | 134 | { 135 | "sys": { 136 | "type": "Array" 137 | }, 138 | "total": 3, 139 | "skip": 0, 140 | "limit": 100, 141 | "items": [ 142 | { 143 | "fields": [ 144 | { 145 | "name": "testowe", 146 | "id": "testowe", 147 | "type": "Link", 148 | "uiid": "3q907mcb4lc", 149 | "linkType": "Asset", 150 | "required": true, 151 | "localized": true 152 | } 153 | ], 154 | "name": "test", 155 | "sys": { 156 | "id": "26eLfV14SIOeQkse44q4sw", 157 | "type": "ContentType", 158 | "createdAt": "2014-08-22T12:57:43.618Z", 159 | "createdBy": { 160 | "sys": { 161 | "type": "Link", 162 | "linkType": "User", 163 | "id": "1E7acJL8I5XUXAMHQt9Grs" 164 | } 165 | }, 166 | "space": { 167 | "sys": { 168 | "type": "Link", 169 | "linkType": "Space", 170 | "id": "v2umtz8ths9v" 171 | } 172 | }, 173 | "firstPublishedAt": "2014-08-22T12:57:53.093Z", 174 | "publishedCounter": 2, 175 | "publishedAt": "2014-08-22T12:57:58.628Z", 176 | "publishedBy": { 177 | "sys": { 178 | "type": "Link", 179 | "linkType": "User", 180 | "id": "1E7acJL8I5XUXAMHQt9Grs" 181 | } 182 | }, 183 | "publishedVersion": 13, 184 | "version": 14, 185 | "updatedAt": "2014-08-22T12:57:58.633Z", 186 | "updatedBy": { 187 | "sys": { 188 | "type": "Link", 189 | "linkType": "User", 190 | "id": "1E7acJL8I5XUXAMHQt9Grs" 191 | } 192 | } 193 | } 194 | }, 195 | { 196 | "displayField": "title", 197 | "name": "Post", 198 | "description": "", 199 | "fields": [ 200 | { 201 | "id": "title", 202 | "name": "Title", 203 | "type": "Text", 204 | "localized": true, 205 | "uiid": "2sdir2f8kcg" 206 | }, 207 | { 208 | "id": "author", 209 | "name": "Author", 210 | "type": "Text", 211 | "localized": true, 212 | "uiid": "4x1018907pc" 213 | }, 214 | { 215 | "id": "body", 216 | "name": "Body", 217 | "type": "Text", 218 | "localized": true, 219 | "uiid": "4hj7cda89hc" 220 | }, 221 | { 222 | "id": "title_image", 223 | "name": "Title Image", 224 | "type": "Link", 225 | "linkType": "Asset", 226 | "required": true, 227 | "localized": true, 228 | "uiid": "4gcqrcma8lc" 229 | }, 230 | { 231 | "id": "second_image", 232 | "name": "Second Image", 233 | "type": "Link", 234 | "linkType": "Asset", 235 | "localized": true, 236 | "uiid": "40440elrugw" 237 | }, 238 | { 239 | "id": "category", 240 | "name": "Category", 241 | "type": "Link", 242 | "linkType": "Entry", 243 | "uiid": "49vicjvqsxs", 244 | "localized": true 245 | } 246 | ], 247 | "sys": { 248 | "id": "post_content_type", 249 | "type": "ContentType", 250 | "createdAt": "2014-08-21T13:32:30.401Z", 251 | "createdBy": { 252 | "sys": { 253 | "type": "Link", 254 | "linkType": "User", 255 | "id": "1E7acJL8I5XUXAMHQt9Grs" 256 | } 257 | }, 258 | "space": { 259 | "sys": { 260 | "type": "Link", 261 | "linkType": "Space", 262 | "id": "v2umtz8ths9v" 263 | } 264 | }, 265 | "firstPublishedAt": "2014-08-21T13:32:43.385Z", 266 | "publishedCounter": 2, 267 | "publishedAt": "2014-08-27T09:18:36.995Z", 268 | "publishedBy": { 269 | "sys": { 270 | "type": "Link", 271 | "linkType": "User", 272 | "id": "1E7acJL8I5XUXAMHQt9Grs" 273 | } 274 | }, 275 | "publishedVersion": 11, 276 | "version": 12, 277 | "updatedAt": "2014-08-27T09:18:37.003Z", 278 | "updatedBy": { 279 | "sys": { 280 | "type": "Link", 281 | "linkType": "User", 282 | "id": "1E7acJL8I5XUXAMHQt9Grs" 283 | } 284 | } 285 | } 286 | }, 287 | { 288 | "displayField": "name", 289 | "name": "Category", 290 | "description": "", 291 | "fields": [ 292 | { 293 | "id": "name", 294 | "name": "Name", 295 | "type": "Text", 296 | "localized": true, 297 | "uiid": "3ic0t3qi51c" 298 | }, 299 | { 300 | "id": "description", 301 | "name": "Description", 302 | "type": "Text", 303 | "localized": false, 304 | "uiid": "38xiq8fobnk" 305 | } 306 | ], 307 | "sys": { 308 | "id": "category_content_type", 309 | "type": "ContentType", 310 | "createdAt": "2014-08-21T13:32:20.955Z", 311 | "createdBy": { 312 | "sys": { 313 | "type": "Link", 314 | "linkType": "User", 315 | "id": "1E7acJL8I5XUXAMHQt9Grs" 316 | } 317 | }, 318 | "space": { 319 | "sys": { 320 | "type": "Link", 321 | "linkType": "Space", 322 | "id": "v2umtz8ths9v" 323 | } 324 | }, 325 | "firstPublishedAt": "2014-08-21T13:32:27.109Z", 326 | "publishedCounter": 8, 327 | "publishedAt": "2014-09-04T18:02:17.407Z", 328 | "publishedBy": { 329 | "sys": { 330 | "type": "Link", 331 | "linkType": "User", 332 | "id": "1E7acJL8I5XUXAMHQt9Grs" 333 | } 334 | }, 335 | "publishedVersion": 31, 336 | "version": 32, 337 | "updatedAt": "2014-09-04T18:02:17.415Z", 338 | "updatedBy": { 339 | "sys": { 340 | "type": "Link", 341 | "linkType": "User", 342 | "id": "1E7acJL8I5XUXAMHQt9Grs" 343 | } 344 | } 345 | } 346 | } 347 | ] 348 | } 349 | http_version: 350 | recorded_at: Fri, 05 Sep 2014 12:16:00 GMT 351 | - request: 352 | method: get 353 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/locales 354 | body: 355 | encoding: US-ASCII 356 | string: '' 357 | headers: 358 | User-Agent: 359 | - RubyContenfulManagementGem/0.1.0 360 | Authorization: 361 | - Bearer 362 | Content-Type: 363 | - application/vnd.contentful.management.v1+json 364 | Content-Length: 365 | - '0' 366 | Host: 367 | - api.contentful.com 368 | response: 369 | status: 370 | code: 200 371 | message: OK 372 | headers: 373 | "^access-Control-Expose-Headers": 374 | - Etag 375 | Accept-Ranges: 376 | - bytes 377 | Access-Control-Allow-Headers: 378 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 379 | Access-Control-Allow-Methods: 380 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 381 | Access-Control-Allow-Origin: 382 | - "*" 383 | Access-Control-Max-Age: 384 | - '1728000' 385 | Cache-Control: 386 | - max-age=0 387 | Content-Type: 388 | - application/vnd.contentful.management.v1+json 389 | Date: 390 | - Fri, 05 Sep 2014 12:15:29 GMT 391 | Etag: 392 | - '"30e7a28ed3dbfc3b90bc324b03fb16a8"' 393 | Server: 394 | - nginx 395 | Status: 396 | - 200 OK 397 | X-Contentful-Request-Id: 398 | - 85f-935741973 399 | Content-Length: 400 | - '2619' 401 | Connection: 402 | - keep-alive 403 | body: 404 | encoding: UTF-8 405 | string: | 406 | { 407 | "sys":{ 408 | "type":"Array" 409 | }, 410 | "items":[ 411 | { 412 | "sys":{ 413 | "type":"Locale", 414 | "id":"3KpVOfIfikrLpwqCa49ami", 415 | "version":0, 416 | "space":{ 417 | "sys":{ 418 | "type":"Link", 419 | "linkType":"Space", 420 | "id":"v2umtz8ths9v" 421 | } 422 | }, 423 | "createdBy":{ 424 | "sys":{ 425 | "type":"Link", 426 | "linkType":"User", 427 | "id":"1E7acJL8I5XUXAMHQt9Grs" 428 | } 429 | }, 430 | "createdAt":"2014-08-21T13:32:12Z", 431 | "updatedBy":{ 432 | "sys":{ 433 | "type":"Link", 434 | "linkType":"User", 435 | "id":"1E7acJL8I5XUXAMHQt9Grs" 436 | } 437 | }, 438 | "updatedAt":"2014-08-21T13:32:12Z" 439 | }, 440 | "name":"U.S. English", 441 | "code":"en-US", 442 | "default":true, 443 | "contentManagementApi":true, 444 | "publish":true, 445 | "contentDeliveryApi":true 446 | }, 447 | { 448 | "sys":{ 449 | "type":"Locale", 450 | "id":"3PFj46pytOXQnNSEzqNsaO", 451 | "version":0, 452 | "space":{ 453 | "sys":{ 454 | "type":"Link", 455 | "linkType":"Space", 456 | "id":"v2umtz8ths9v" 457 | } 458 | }, 459 | "createdBy":{ 460 | "sys":{ 461 | "type":"Link", 462 | "linkType":"User", 463 | "id":"1E7acJL8I5XUXAMHQt9Grs" 464 | } 465 | }, 466 | "createdAt":"2014-08-21T13:32:16Z", 467 | "updatedBy":{ 468 | "sys":{ 469 | "type":"Link", 470 | "linkType":"User", 471 | "id":"1E7acJL8I5XUXAMHQt9Grs" 472 | } 473 | }, 474 | "updatedAt":"2014-08-21T13:32:16Z" 475 | }, 476 | "name":"German", 477 | "code":"de-DE", 478 | "default":false, 479 | "contentManagementApi":true, 480 | "publish":true, 481 | "contentDeliveryApi":true 482 | }, 483 | { 484 | "sys":{ 485 | "type":"Locale", 486 | "id":"3RN3vNgufcurpT9L5o8PBA", 487 | "version":0, 488 | "space":{ 489 | "sys":{ 490 | "type":"Link", 491 | "linkType":"Space", 492 | "id":"v2umtz8ths9v" 493 | } 494 | }, 495 | "createdBy":{ 496 | "sys":{ 497 | "type":"Link", 498 | "linkType":"User", 499 | "id":"1E7acJL8I5XUXAMHQt9Grs" 500 | } 501 | }, 502 | "createdAt":"2014-08-21T13:32:18Z", 503 | "updatedBy":{ 504 | "sys":{ 505 | "type":"Link", 506 | "linkType":"User", 507 | "id":"1E7acJL8I5XUXAMHQt9Grs" 508 | } 509 | }, 510 | "updatedAt":"2014-08-21T13:32:18Z" 511 | }, 512 | "name":"Polish", 513 | "code":"pl-PL", 514 | "default":false, 515 | "contentManagementApi":true, 516 | "publish":true, 517 | "contentDeliveryApi":true 518 | } 519 | ], 520 | "total":3, 521 | "limit":25, 522 | "skip":0} 523 | http_version: 524 | recorded_at: Fri, 05 Sep 2014 12:16:01 GMT 525 | recorded_with: VCR 2.9.2 526 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/image/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.contentful.com/spaces/v2umtz8ths9v 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - RubyContenfulManagementGem/0.1.0 12 | Authorization: 13 | - Bearer 14 | Content-Type: 15 | - application/vnd.contentful.management.v1+json 16 | Content-Length: 17 | - '0' 18 | Host: 19 | - api.contentful.com 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | "^access-Control-Expose-Headers": 26 | - Etag 27 | Accept-Ranges: 28 | - bytes 29 | Access-Control-Allow-Headers: 30 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 31 | Access-Control-Allow-Methods: 32 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 33 | Access-Control-Allow-Origin: 34 | - "*" 35 | Access-Control-Max-Age: 36 | - '1728000' 37 | Cache-Control: 38 | - max-age=0 39 | Content-Type: 40 | - application/vnd.contentful.management.v1+json 41 | Date: 42 | - Fri, 05 Sep 2014 12:15:19 GMT 43 | Etag: 44 | - '"35407b8a88882fe5717a4701910f6ce7"' 45 | Server: 46 | - nginx 47 | Status: 48 | - 200 OK 49 | X-Contentful-Request-Id: 50 | - 85f-935741938 51 | Content-Length: 52 | - '459' 53 | Connection: 54 | - keep-alive 55 | body: 56 | encoding: UTF-8 57 | string: | 58 | { 59 | "sys":{ 60 | "type":"Space", 61 | "id":"v2umtz8ths9v", 62 | "version":1, 63 | "createdBy":{ 64 | "sys":{ 65 | "type":"Link", 66 | "linkType":"User", 67 | "id":"1E7acJL8I5XUXAMHQt9Grs" 68 | } 69 | }, 70 | "createdAt":"2014-08-21T13:32:11Z", 71 | "updatedBy":{ 72 | "sys":{ 73 | "type":"Link", 74 | "linkType":"User", 75 | "id":"1E7acJL8I5XUXAMHQt9Grs" 76 | } 77 | }, 78 | "updatedAt":"2014-08-21T13:32:12Z" 79 | }, 80 | "name":"CMA Demo Rails App"} 81 | http_version: 82 | recorded_at: Fri, 05 Sep 2014 12:15:51 GMT 83 | - request: 84 | method: get 85 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types 86 | body: 87 | encoding: US-ASCII 88 | string: '' 89 | headers: 90 | User-Agent: 91 | - RubyContenfulManagementGem/0.1.0 92 | Authorization: 93 | - Bearer 94 | Content-Type: 95 | - application/vnd.contentful.management.v1+json 96 | Content-Length: 97 | - '0' 98 | Host: 99 | - api.contentful.com 100 | response: 101 | status: 102 | code: 200 103 | message: OK 104 | headers: 105 | "^access-Control-Expose-Headers": 106 | - Etag 107 | Access-Control-Allow-Headers: 108 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 109 | Access-Control-Allow-Methods: 110 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 111 | Access-Control-Allow-Origin: 112 | - "*" 113 | Access-Control-Max-Age: 114 | - '1728000' 115 | Cf-Space-Id: 116 | - v2umtz8ths9v 117 | Content-Type: 118 | - application/vnd.contentful.management.v1+json 119 | Date: 120 | - Fri, 05 Sep 2014 12:15:20 GMT 121 | Etag: 122 | - '"2a8abfd957b4ad9b6b47f853bd58078a"' 123 | Server: 124 | - nginx 125 | X-Powered-By: 126 | - Express 127 | Content-Length: 128 | - '5193' 129 | Connection: 130 | - keep-alive 131 | body: 132 | encoding: UTF-8 133 | string: | 134 | { 135 | "sys": { 136 | "type": "Array" 137 | }, 138 | "total": 3, 139 | "skip": 0, 140 | "limit": 100, 141 | "items": [ 142 | { 143 | "fields": [ 144 | { 145 | "name": "testowe", 146 | "id": "testowe", 147 | "type": "Link", 148 | "uiid": "3q907mcb4lc", 149 | "linkType": "Asset", 150 | "required": true, 151 | "localized": true 152 | } 153 | ], 154 | "name": "test", 155 | "sys": { 156 | "id": "26eLfV14SIOeQkse44q4sw", 157 | "type": "ContentType", 158 | "createdAt": "2014-08-22T12:57:43.618Z", 159 | "createdBy": { 160 | "sys": { 161 | "type": "Link", 162 | "linkType": "User", 163 | "id": "1E7acJL8I5XUXAMHQt9Grs" 164 | } 165 | }, 166 | "space": { 167 | "sys": { 168 | "type": "Link", 169 | "linkType": "Space", 170 | "id": "v2umtz8ths9v" 171 | } 172 | }, 173 | "firstPublishedAt": "2014-08-22T12:57:53.093Z", 174 | "publishedCounter": 2, 175 | "publishedAt": "2014-08-22T12:57:58.628Z", 176 | "publishedBy": { 177 | "sys": { 178 | "type": "Link", 179 | "linkType": "User", 180 | "id": "1E7acJL8I5XUXAMHQt9Grs" 181 | } 182 | }, 183 | "publishedVersion": 13, 184 | "version": 14, 185 | "updatedAt": "2014-08-22T12:57:58.633Z", 186 | "updatedBy": { 187 | "sys": { 188 | "type": "Link", 189 | "linkType": "User", 190 | "id": "1E7acJL8I5XUXAMHQt9Grs" 191 | } 192 | } 193 | } 194 | }, 195 | { 196 | "displayField": "title", 197 | "name": "Post", 198 | "description": "", 199 | "fields": [ 200 | { 201 | "id": "title", 202 | "name": "Title", 203 | "type": "Text", 204 | "localized": true, 205 | "uiid": "2sdir2f8kcg" 206 | }, 207 | { 208 | "id": "author", 209 | "name": "Author", 210 | "type": "Text", 211 | "localized": true, 212 | "uiid": "4x1018907pc" 213 | }, 214 | { 215 | "id": "body", 216 | "name": "Body", 217 | "type": "Text", 218 | "localized": true, 219 | "uiid": "4hj7cda89hc" 220 | }, 221 | { 222 | "id": "title_image", 223 | "name": "Title Image", 224 | "type": "Link", 225 | "linkType": "Asset", 226 | "required": true, 227 | "localized": true, 228 | "uiid": "4gcqrcma8lc" 229 | }, 230 | { 231 | "id": "second_image", 232 | "name": "Second Image", 233 | "type": "Link", 234 | "linkType": "Asset", 235 | "localized": true, 236 | "uiid": "40440elrugw" 237 | }, 238 | { 239 | "id": "category", 240 | "name": "Category", 241 | "type": "Link", 242 | "linkType": "Entry", 243 | "uiid": "49vicjvqsxs", 244 | "localized": true 245 | } 246 | ], 247 | "sys": { 248 | "id": "post_content_type", 249 | "type": "ContentType", 250 | "createdAt": "2014-08-21T13:32:30.401Z", 251 | "createdBy": { 252 | "sys": { 253 | "type": "Link", 254 | "linkType": "User", 255 | "id": "1E7acJL8I5XUXAMHQt9Grs" 256 | } 257 | }, 258 | "space": { 259 | "sys": { 260 | "type": "Link", 261 | "linkType": "Space", 262 | "id": "v2umtz8ths9v" 263 | } 264 | }, 265 | "firstPublishedAt": "2014-08-21T13:32:43.385Z", 266 | "publishedCounter": 2, 267 | "publishedAt": "2014-08-27T09:18:36.995Z", 268 | "publishedBy": { 269 | "sys": { 270 | "type": "Link", 271 | "linkType": "User", 272 | "id": "1E7acJL8I5XUXAMHQt9Grs" 273 | } 274 | }, 275 | "publishedVersion": 11, 276 | "version": 12, 277 | "updatedAt": "2014-08-27T09:18:37.003Z", 278 | "updatedBy": { 279 | "sys": { 280 | "type": "Link", 281 | "linkType": "User", 282 | "id": "1E7acJL8I5XUXAMHQt9Grs" 283 | } 284 | } 285 | } 286 | }, 287 | { 288 | "displayField": "name", 289 | "name": "Category", 290 | "description": "", 291 | "fields": [ 292 | { 293 | "id": "name", 294 | "name": "Name", 295 | "type": "Text", 296 | "localized": true, 297 | "uiid": "3ic0t3qi51c" 298 | }, 299 | { 300 | "id": "description", 301 | "name": "Description", 302 | "type": "Text", 303 | "localized": false, 304 | "uiid": "38xiq8fobnk" 305 | } 306 | ], 307 | "sys": { 308 | "id": "category_content_type", 309 | "type": "ContentType", 310 | "createdAt": "2014-08-21T13:32:20.955Z", 311 | "createdBy": { 312 | "sys": { 313 | "type": "Link", 314 | "linkType": "User", 315 | "id": "1E7acJL8I5XUXAMHQt9Grs" 316 | } 317 | }, 318 | "space": { 319 | "sys": { 320 | "type": "Link", 321 | "linkType": "Space", 322 | "id": "v2umtz8ths9v" 323 | } 324 | }, 325 | "firstPublishedAt": "2014-08-21T13:32:27.109Z", 326 | "publishedCounter": 8, 327 | "publishedAt": "2014-09-04T18:02:17.407Z", 328 | "publishedBy": { 329 | "sys": { 330 | "type": "Link", 331 | "linkType": "User", 332 | "id": "1E7acJL8I5XUXAMHQt9Grs" 333 | } 334 | }, 335 | "publishedVersion": 31, 336 | "version": 32, 337 | "updatedAt": "2014-09-04T18:02:17.415Z", 338 | "updatedBy": { 339 | "sys": { 340 | "type": "Link", 341 | "linkType": "User", 342 | "id": "1E7acJL8I5XUXAMHQt9Grs" 343 | } 344 | } 345 | } 346 | } 347 | ] 348 | } 349 | http_version: 350 | recorded_at: Fri, 05 Sep 2014 12:15:51 GMT 351 | - request: 352 | method: get 353 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/assets/6rsv917hReaKM8CyIGSES 354 | body: 355 | encoding: US-ASCII 356 | string: '' 357 | headers: 358 | User-Agent: 359 | - RubyContenfulManagementGem/0.1.0 360 | Authorization: 361 | - Bearer 362 | Content-Type: 363 | - application/vnd.contentful.management.v1+json 364 | Content-Length: 365 | - '0' 366 | Host: 367 | - api.contentful.com 368 | response: 369 | status: 370 | code: 200 371 | message: OK 372 | headers: 373 | "^access-Control-Expose-Headers": 374 | - Etag 375 | Access-Control-Allow-Headers: 376 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 377 | Access-Control-Allow-Methods: 378 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 379 | Access-Control-Allow-Origin: 380 | - "*" 381 | Access-Control-Max-Age: 382 | - '1728000' 383 | Cf-Space-Id: 384 | - v2umtz8ths9v 385 | Content-Type: 386 | - application/vnd.contentful.management.v1+json 387 | Date: 388 | - Fri, 05 Sep 2014 12:15:20 GMT 389 | Etag: 390 | - '"49fdb4434247f99047ad0f564df8267c"' 391 | Server: 392 | - nginx 393 | X-Powered-By: 394 | - Express 395 | Content-Length: 396 | - '1924' 397 | Connection: 398 | - keep-alive 399 | body: 400 | encoding: UTF-8 401 | string: | 402 | { 403 | "fields": { 404 | "title": { 405 | "en-US": "Test name", 406 | "de-DE": "de create", 407 | "pl-PL": "pl create" 408 | }, 409 | "description": { 410 | "en-US": "Test description", 411 | "de-DE": "desc de", 412 | "pl-PL": "desc pl " 413 | }, 414 | "file": { 415 | "en-US": { 416 | "contentType": "image/jpeg", 417 | "fileName": "Test name", 418 | "details": { 419 | "image": { 420 | "width": 1280, 421 | "height": 1920 422 | }, 423 | "size": 2584366 424 | }, 425 | "url": "//images.contentful.com/v2umtz8ths9v/6rsv917hReaKM8CyIGSES/daa75009fdcf3f47126f19525f480f31/Test_name" 426 | }, 427 | "de-DE": { 428 | "fileName": "de create", 429 | "contentType": "image/jpg", 430 | "details": { 431 | "image": { 432 | "width": 650, 433 | "height": 650 434 | }, 435 | "size": 94751 436 | }, 437 | "url": "//images.contentful.com/v2umtz8ths9v/6rsv917hReaKM8CyIGSES/a1705f0f07d868dc97bcdbdc44a452cf/de_create" 438 | }, 439 | "pl-PL": { 440 | "fileName": "pl create", 441 | "contentType": "image/jpg", 442 | "details": { 443 | "image": { 444 | "width": 1680, 445 | "height": 1050 446 | }, 447 | "size": 970214 448 | }, 449 | "url": "//images.contentful.com/v2umtz8ths9v/6rsv917hReaKM8CyIGSES/135acd68aadae5b898f0f4cc5d5dcded/pl_create" 450 | } 451 | } 452 | }, 453 | "sys": { 454 | "id": "6rsv917hReaKM8CyIGSES", 455 | "type": "Asset", 456 | "createdAt": "2014-09-04T11:07:19.580Z", 457 | "createdBy": { 458 | "sys": { 459 | "type": "Link", 460 | "linkType": "User", 461 | "id": "1E7acJL8I5XUXAMHQt9Grs" 462 | } 463 | }, 464 | "space": { 465 | "sys": { 466 | "type": "Link", 467 | "linkType": "Space", 468 | "id": "v2umtz8ths9v" 469 | } 470 | }, 471 | "version": 11, 472 | "updatedAt": "2014-09-05T12:07:08.075Z", 473 | "updatedBy": { 474 | "sys": { 475 | "type": "Link", 476 | "linkType": "User", 477 | "id": "1E7acJL8I5XUXAMHQt9Grs" 478 | } 479 | } 480 | } 481 | } 482 | http_version: 483 | recorded_at: Fri, 05 Sep 2014 12:15:52 GMT 484 | - request: 485 | method: get 486 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/locales 487 | body: 488 | encoding: US-ASCII 489 | string: '' 490 | headers: 491 | User-Agent: 492 | - RubyContenfulManagementGem/0.1.0 493 | Authorization: 494 | - Bearer 495 | Content-Type: 496 | - application/vnd.contentful.management.v1+json 497 | Content-Length: 498 | - '0' 499 | Host: 500 | - api.contentful.com 501 | response: 502 | status: 503 | code: 200 504 | message: OK 505 | headers: 506 | "^access-Control-Expose-Headers": 507 | - Etag 508 | Accept-Ranges: 509 | - bytes 510 | Access-Control-Allow-Headers: 511 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 512 | Access-Control-Allow-Methods: 513 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 514 | Access-Control-Allow-Origin: 515 | - "*" 516 | Access-Control-Max-Age: 517 | - '1728000' 518 | Cache-Control: 519 | - max-age=0 520 | Content-Type: 521 | - application/vnd.contentful.management.v1+json 522 | Date: 523 | - Fri, 05 Sep 2014 12:15:21 GMT 524 | Etag: 525 | - '"30e7a28ed3dbfc3b90bc324b03fb16a8"' 526 | Server: 527 | - nginx 528 | Status: 529 | - 200 OK 530 | X-Contentful-Request-Id: 531 | - 71a-914510631 532 | Content-Length: 533 | - '2619' 534 | Connection: 535 | - keep-alive 536 | body: 537 | encoding: UTF-8 538 | string: | 539 | { 540 | "sys":{ 541 | "type":"Array" 542 | }, 543 | "items":[ 544 | { 545 | "sys":{ 546 | "type":"Locale", 547 | "id":"3KpVOfIfikrLpwqCa49ami", 548 | "version":0, 549 | "space":{ 550 | "sys":{ 551 | "type":"Link", 552 | "linkType":"Space", 553 | "id":"v2umtz8ths9v" 554 | } 555 | }, 556 | "createdBy":{ 557 | "sys":{ 558 | "type":"Link", 559 | "linkType":"User", 560 | "id":"1E7acJL8I5XUXAMHQt9Grs" 561 | } 562 | }, 563 | "createdAt":"2014-08-21T13:32:12Z", 564 | "updatedBy":{ 565 | "sys":{ 566 | "type":"Link", 567 | "linkType":"User", 568 | "id":"1E7acJL8I5XUXAMHQt9Grs" 569 | } 570 | }, 571 | "updatedAt":"2014-08-21T13:32:12Z" 572 | }, 573 | "name":"U.S. English", 574 | "code":"en-US", 575 | "default":true, 576 | "contentManagementApi":true, 577 | "publish":true, 578 | "contentDeliveryApi":true 579 | }, 580 | { 581 | "sys":{ 582 | "type":"Locale", 583 | "id":"3PFj46pytOXQnNSEzqNsaO", 584 | "version":0, 585 | "space":{ 586 | "sys":{ 587 | "type":"Link", 588 | "linkType":"Space", 589 | "id":"v2umtz8ths9v" 590 | } 591 | }, 592 | "createdBy":{ 593 | "sys":{ 594 | "type":"Link", 595 | "linkType":"User", 596 | "id":"1E7acJL8I5XUXAMHQt9Grs" 597 | } 598 | }, 599 | "createdAt":"2014-08-21T13:32:16Z", 600 | "updatedBy":{ 601 | "sys":{ 602 | "type":"Link", 603 | "linkType":"User", 604 | "id":"1E7acJL8I5XUXAMHQt9Grs" 605 | } 606 | }, 607 | "updatedAt":"2014-08-21T13:32:16Z" 608 | }, 609 | "name":"German", 610 | "code":"de-DE", 611 | "default":false, 612 | "contentManagementApi":true, 613 | "publish":true, 614 | "contentDeliveryApi":true 615 | }, 616 | { 617 | "sys":{ 618 | "type":"Locale", 619 | "id":"3RN3vNgufcurpT9L5o8PBA", 620 | "version":0, 621 | "space":{ 622 | "sys":{ 623 | "type":"Link", 624 | "linkType":"Space", 625 | "id":"v2umtz8ths9v" 626 | } 627 | }, 628 | "createdBy":{ 629 | "sys":{ 630 | "type":"Link", 631 | "linkType":"User", 632 | "id":"1E7acJL8I5XUXAMHQt9Grs" 633 | } 634 | }, 635 | "createdAt":"2014-08-21T13:32:18Z", 636 | "updatedBy":{ 637 | "sys":{ 638 | "type":"Link", 639 | "linkType":"User", 640 | "id":"1E7acJL8I5XUXAMHQt9Grs" 641 | } 642 | }, 643 | "updatedAt":"2014-08-21T13:32:18Z" 644 | }, 645 | "name":"Polish", 646 | "code":"pl-PL", 647 | "default":false, 648 | "contentManagementApi":true, 649 | "publish":true, 650 | "contentDeliveryApi":true 651 | } 652 | ], 653 | "total":3, 654 | "limit":25, 655 | "skip":0} 656 | http_version: 657 | recorded_at: Fri, 05 Sep 2014 12:15:52 GMT 658 | - request: 659 | method: delete 660 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/assets/6rsv917hReaKM8CyIGSES 661 | body: 662 | encoding: US-ASCII 663 | string: '' 664 | headers: 665 | User-Agent: 666 | - RubyContenfulManagementGem/0.1.0 667 | Authorization: 668 | - Bearer 669 | Content-Type: 670 | - application/vnd.contentful.management.v1+json 671 | Content-Length: 672 | - '0' 673 | Host: 674 | - api.contentful.com 675 | response: 676 | status: 677 | code: 204 678 | message: No Content 679 | headers: 680 | "^access-Control-Expose-Headers": 681 | - Etag 682 | Access-Control-Allow-Headers: 683 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 684 | Access-Control-Allow-Methods: 685 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 686 | Access-Control-Allow-Origin: 687 | - "*" 688 | Access-Control-Max-Age: 689 | - '1728000' 690 | Cf-Space-Id: 691 | - v2umtz8ths9v 692 | Content-Type: 693 | - application/vnd.contentful.management.v1+json 694 | Date: 695 | - Fri, 05 Sep 2014 12:15:22 GMT 696 | Server: 697 | - nginx 698 | X-Powered-By: 699 | - Express 700 | Connection: 701 | - keep-alive 702 | body: 703 | encoding: UTF-8 704 | string: '' 705 | http_version: 706 | recorded_at: Fri, 05 Sep 2014 12:15:54 GMT 707 | recorded_with: VCR 2.9.2 708 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/category/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.contentful.com/spaces/v2umtz8ths9v 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - RubyContenfulManagementGem/0.1.0 12 | Authorization: 13 | - Bearer 14 | Content-Type: 15 | - application/vnd.contentful.management.v1+json 16 | Content-Length: 17 | - '0' 18 | Host: 19 | - api.contentful.com 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | "^access-Control-Expose-Headers": 26 | - Etag 27 | Accept-Ranges: 28 | - bytes 29 | Access-Control-Allow-Headers: 30 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 31 | Access-Control-Allow-Methods: 32 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 33 | Access-Control-Allow-Origin: 34 | - "*" 35 | Access-Control-Max-Age: 36 | - '1728000' 37 | Cache-Control: 38 | - max-age=0 39 | Content-Type: 40 | - application/vnd.contentful.management.v1+json 41 | Date: 42 | - Fri, 05 Sep 2014 11:38:07 GMT 43 | Etag: 44 | - '"35407b8a88882fe5717a4701910f6ce7"' 45 | Server: 46 | - nginx 47 | Status: 48 | - 200 OK 49 | X-Contentful-Request-Id: 50 | - 85f-935733829 51 | Content-Length: 52 | - '459' 53 | Connection: 54 | - keep-alive 55 | body: 56 | encoding: UTF-8 57 | string: | 58 | { 59 | "sys":{ 60 | "type":"Space", 61 | "id":"v2umtz8ths9v", 62 | "version":1, 63 | "createdBy":{ 64 | "sys":{ 65 | "type":"Link", 66 | "linkType":"User", 67 | "id":"1E7acJL8I5XUXAMHQt9Grs" 68 | } 69 | }, 70 | "createdAt":"2014-08-21T13:32:11Z", 71 | "updatedBy":{ 72 | "sys":{ 73 | "type":"Link", 74 | "linkType":"User", 75 | "id":"1E7acJL8I5XUXAMHQt9Grs" 76 | } 77 | }, 78 | "updatedAt":"2014-08-21T13:32:12Z" 79 | }, 80 | "name":"CMA Demo Rails App"} 81 | http_version: 82 | recorded_at: Fri, 05 Sep 2014 11:38:39 GMT 83 | - request: 84 | method: get 85 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types 86 | body: 87 | encoding: US-ASCII 88 | string: '' 89 | headers: 90 | User-Agent: 91 | - RubyContenfulManagementGem/0.1.0 92 | Authorization: 93 | - Bearer 94 | Content-Type: 95 | - application/vnd.contentful.management.v1+json 96 | Content-Length: 97 | - '0' 98 | Host: 99 | - api.contentful.com 100 | response: 101 | status: 102 | code: 200 103 | message: OK 104 | headers: 105 | "^access-Control-Expose-Headers": 106 | - Etag 107 | Access-Control-Allow-Headers: 108 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 109 | Access-Control-Allow-Methods: 110 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 111 | Access-Control-Allow-Origin: 112 | - "*" 113 | Access-Control-Max-Age: 114 | - '1728000' 115 | Cf-Space-Id: 116 | - v2umtz8ths9v 117 | Content-Type: 118 | - application/vnd.contentful.management.v1+json 119 | Date: 120 | - Fri, 05 Sep 2014 11:38:07 GMT 121 | Etag: 122 | - '"2a8abfd957b4ad9b6b47f853bd58078a"' 123 | Server: 124 | - nginx 125 | X-Powered-By: 126 | - Express 127 | Content-Length: 128 | - '5193' 129 | Connection: 130 | - keep-alive 131 | body: 132 | encoding: UTF-8 133 | string: | 134 | { 135 | "sys": { 136 | "type": "Array" 137 | }, 138 | "total": 3, 139 | "skip": 0, 140 | "limit": 100, 141 | "items": [ 142 | { 143 | "fields": [ 144 | { 145 | "name": "testowe", 146 | "id": "testowe", 147 | "type": "Link", 148 | "uiid": "3q907mcb4lc", 149 | "linkType": "Asset", 150 | "required": true, 151 | "localized": true 152 | } 153 | ], 154 | "name": "test", 155 | "sys": { 156 | "id": "26eLfV14SIOeQkse44q4sw", 157 | "type": "ContentType", 158 | "createdAt": "2014-08-22T12:57:43.618Z", 159 | "createdBy": { 160 | "sys": { 161 | "type": "Link", 162 | "linkType": "User", 163 | "id": "1E7acJL8I5XUXAMHQt9Grs" 164 | } 165 | }, 166 | "space": { 167 | "sys": { 168 | "type": "Link", 169 | "linkType": "Space", 170 | "id": "v2umtz8ths9v" 171 | } 172 | }, 173 | "firstPublishedAt": "2014-08-22T12:57:53.093Z", 174 | "publishedCounter": 2, 175 | "publishedAt": "2014-08-22T12:57:58.628Z", 176 | "publishedBy": { 177 | "sys": { 178 | "type": "Link", 179 | "linkType": "User", 180 | "id": "1E7acJL8I5XUXAMHQt9Grs" 181 | } 182 | }, 183 | "publishedVersion": 13, 184 | "version": 14, 185 | "updatedAt": "2014-08-22T12:57:58.633Z", 186 | "updatedBy": { 187 | "sys": { 188 | "type": "Link", 189 | "linkType": "User", 190 | "id": "1E7acJL8I5XUXAMHQt9Grs" 191 | } 192 | } 193 | } 194 | }, 195 | { 196 | "displayField": "title", 197 | "name": "Post", 198 | "description": "", 199 | "fields": [ 200 | { 201 | "id": "title", 202 | "name": "Title", 203 | "type": "Text", 204 | "localized": true, 205 | "uiid": "2sdir2f8kcg" 206 | }, 207 | { 208 | "id": "author", 209 | "name": "Author", 210 | "type": "Text", 211 | "localized": true, 212 | "uiid": "4x1018907pc" 213 | }, 214 | { 215 | "id": "body", 216 | "name": "Body", 217 | "type": "Text", 218 | "localized": true, 219 | "uiid": "4hj7cda89hc" 220 | }, 221 | { 222 | "id": "title_image", 223 | "name": "Title Image", 224 | "type": "Link", 225 | "linkType": "Asset", 226 | "required": true, 227 | "localized": true, 228 | "uiid": "4gcqrcma8lc" 229 | }, 230 | { 231 | "id": "second_image", 232 | "name": "Second Image", 233 | "type": "Link", 234 | "linkType": "Asset", 235 | "localized": true, 236 | "uiid": "40440elrugw" 237 | }, 238 | { 239 | "id": "category", 240 | "name": "Category", 241 | "type": "Link", 242 | "linkType": "Entry", 243 | "uiid": "49vicjvqsxs", 244 | "localized": true 245 | } 246 | ], 247 | "sys": { 248 | "id": "post_content_type", 249 | "type": "ContentType", 250 | "createdAt": "2014-08-21T13:32:30.401Z", 251 | "createdBy": { 252 | "sys": { 253 | "type": "Link", 254 | "linkType": "User", 255 | "id": "1E7acJL8I5XUXAMHQt9Grs" 256 | } 257 | }, 258 | "space": { 259 | "sys": { 260 | "type": "Link", 261 | "linkType": "Space", 262 | "id": "v2umtz8ths9v" 263 | } 264 | }, 265 | "firstPublishedAt": "2014-08-21T13:32:43.385Z", 266 | "publishedCounter": 2, 267 | "publishedAt": "2014-08-27T09:18:36.995Z", 268 | "publishedBy": { 269 | "sys": { 270 | "type": "Link", 271 | "linkType": "User", 272 | "id": "1E7acJL8I5XUXAMHQt9Grs" 273 | } 274 | }, 275 | "publishedVersion": 11, 276 | "version": 12, 277 | "updatedAt": "2014-08-27T09:18:37.003Z", 278 | "updatedBy": { 279 | "sys": { 280 | "type": "Link", 281 | "linkType": "User", 282 | "id": "1E7acJL8I5XUXAMHQt9Grs" 283 | } 284 | } 285 | } 286 | }, 287 | { 288 | "displayField": "name", 289 | "name": "Category", 290 | "description": "", 291 | "fields": [ 292 | { 293 | "id": "name", 294 | "name": "Name", 295 | "type": "Text", 296 | "localized": true, 297 | "uiid": "3ic0t3qi51c" 298 | }, 299 | { 300 | "id": "description", 301 | "name": "Description", 302 | "type": "Text", 303 | "localized": false, 304 | "uiid": "38xiq8fobnk" 305 | } 306 | ], 307 | "sys": { 308 | "id": "category_content_type", 309 | "type": "ContentType", 310 | "createdAt": "2014-08-21T13:32:20.955Z", 311 | "createdBy": { 312 | "sys": { 313 | "type": "Link", 314 | "linkType": "User", 315 | "id": "1E7acJL8I5XUXAMHQt9Grs" 316 | } 317 | }, 318 | "space": { 319 | "sys": { 320 | "type": "Link", 321 | "linkType": "Space", 322 | "id": "v2umtz8ths9v" 323 | } 324 | }, 325 | "firstPublishedAt": "2014-08-21T13:32:27.109Z", 326 | "publishedCounter": 8, 327 | "publishedAt": "2014-09-04T18:02:17.407Z", 328 | "publishedBy": { 329 | "sys": { 330 | "type": "Link", 331 | "linkType": "User", 332 | "id": "1E7acJL8I5XUXAMHQt9Grs" 333 | } 334 | }, 335 | "publishedVersion": 31, 336 | "version": 32, 337 | "updatedAt": "2014-09-04T18:02:17.415Z", 338 | "updatedBy": { 339 | "sys": { 340 | "type": "Link", 341 | "linkType": "User", 342 | "id": "1E7acJL8I5XUXAMHQt9Grs" 343 | } 344 | } 345 | } 346 | } 347 | ] 348 | } 349 | http_version: 350 | recorded_at: Fri, 05 Sep 2014 11:38:40 GMT 351 | - request: 352 | method: get 353 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/entries/2TfOVAXdVYkMYuAsWsW8EW 354 | body: 355 | encoding: US-ASCII 356 | string: '' 357 | headers: 358 | User-Agent: 359 | - RubyContenfulManagementGem/0.1.0 360 | Authorization: 361 | - Bearer 362 | Content-Type: 363 | - application/vnd.contentful.management.v1+json 364 | Content-Length: 365 | - '0' 366 | Host: 367 | - api.contentful.com 368 | response: 369 | status: 370 | code: 200 371 | message: OK 372 | headers: 373 | "^access-Control-Expose-Headers": 374 | - Etag 375 | Access-Control-Allow-Headers: 376 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 377 | Access-Control-Allow-Methods: 378 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 379 | Access-Control-Allow-Origin: 380 | - "*" 381 | Access-Control-Max-Age: 382 | - '1728000' 383 | Cf-Space-Id: 384 | - v2umtz8ths9v 385 | Content-Type: 386 | - application/vnd.contentful.management.v1+json 387 | Date: 388 | - Fri, 05 Sep 2014 11:38:08 GMT 389 | Etag: 390 | - '"311e7bed728c4a1abcf76127b03a9e96"' 391 | Server: 392 | - nginx 393 | X-Powered-By: 394 | - Express 395 | Content-Length: 396 | - '852' 397 | Connection: 398 | - keep-alive 399 | body: 400 | encoding: UTF-8 401 | string: | 402 | { 403 | "sys": { 404 | "id": "2TfOVAXdVYkMYuAsWsW8EW", 405 | "type": "Entry", 406 | "createdAt": "2014-09-05T11:37:15.072Z", 407 | "createdBy": { 408 | "sys": { 409 | "type": "Link", 410 | "linkType": "User", 411 | "id": "1E7acJL8I5XUXAMHQt9Grs" 412 | } 413 | }, 414 | "space": { 415 | "sys": { 416 | "type": "Link", 417 | "linkType": "Space", 418 | "id": "v2umtz8ths9v" 419 | } 420 | }, 421 | "contentType": { 422 | "sys": { 423 | "type": "Link", 424 | "linkType": "ContentType", 425 | "id": "category_content_type" 426 | } 427 | }, 428 | "version": 7, 429 | "updatedAt": "2014-09-05T11:37:18.303Z", 430 | "updatedBy": { 431 | "sys": { 432 | "type": "Link", 433 | "linkType": "User", 434 | "id": "1E7acJL8I5XUXAMHQt9Grs" 435 | } 436 | } 437 | }, 438 | "fields": { 439 | "name": { 440 | "en-US": "asdasd" 441 | }, 442 | "description": { 443 | "en-US": "asdad" 444 | } 445 | } 446 | } 447 | http_version: 448 | recorded_at: Fri, 05 Sep 2014 11:38:40 GMT 449 | - request: 450 | method: get 451 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types/category_content_type 452 | body: 453 | encoding: US-ASCII 454 | string: '' 455 | headers: 456 | User-Agent: 457 | - RubyContenfulManagementGem/0.1.0 458 | Authorization: 459 | - Bearer 460 | Content-Type: 461 | - application/vnd.contentful.management.v1+json 462 | Content-Length: 463 | - '0' 464 | Host: 465 | - api.contentful.com 466 | response: 467 | status: 468 | code: 200 469 | message: OK 470 | headers: 471 | "^access-Control-Expose-Headers": 472 | - Etag 473 | Access-Control-Allow-Headers: 474 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 475 | Access-Control-Allow-Methods: 476 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 477 | Access-Control-Allow-Origin: 478 | - "*" 479 | Access-Control-Max-Age: 480 | - '1728000' 481 | Cf-Space-Id: 482 | - v2umtz8ths9v 483 | Content-Type: 484 | - application/vnd.contentful.management.v1+json 485 | Date: 486 | - Fri, 05 Sep 2014 11:38:08 GMT 487 | Etag: 488 | - '"46343a08da081aa9a2276b139329768d"' 489 | Server: 490 | - nginx 491 | X-Powered-By: 492 | - Express 493 | Content-Length: 494 | - '1254' 495 | Connection: 496 | - keep-alive 497 | body: 498 | encoding: UTF-8 499 | string: | 500 | { 501 | "displayField": "name", 502 | "name": "Category", 503 | "description": "", 504 | "fields": [ 505 | { 506 | "id": "name", 507 | "name": "Name", 508 | "type": "Text", 509 | "localized": true, 510 | "uiid": "3ic0t3qi51c" 511 | }, 512 | { 513 | "id": "description", 514 | "name": "Description", 515 | "type": "Text", 516 | "localized": false, 517 | "uiid": "38xiq8fobnk" 518 | } 519 | ], 520 | "sys": { 521 | "id": "category_content_type", 522 | "type": "ContentType", 523 | "createdAt": "2014-08-21T13:32:20.955Z", 524 | "createdBy": { 525 | "sys": { 526 | "type": "Link", 527 | "linkType": "User", 528 | "id": "1E7acJL8I5XUXAMHQt9Grs" 529 | } 530 | }, 531 | "space": { 532 | "sys": { 533 | "type": "Link", 534 | "linkType": "Space", 535 | "id": "v2umtz8ths9v" 536 | } 537 | }, 538 | "firstPublishedAt": "2014-08-21T13:32:27.109Z", 539 | "publishedCounter": 8, 540 | "publishedAt": "2014-09-04T18:02:17.407Z", 541 | "publishedBy": { 542 | "sys": { 543 | "type": "Link", 544 | "linkType": "User", 545 | "id": "1E7acJL8I5XUXAMHQt9Grs" 546 | } 547 | }, 548 | "publishedVersion": 31, 549 | "version": 32, 550 | "updatedAt": "2014-09-04T18:02:17.415Z", 551 | "updatedBy": { 552 | "sys": { 553 | "type": "Link", 554 | "linkType": "User", 555 | "id": "1E7acJL8I5XUXAMHQt9Grs" 556 | } 557 | } 558 | } 559 | } 560 | http_version: 561 | recorded_at: Fri, 05 Sep 2014 11:38:41 GMT 562 | - request: 563 | method: get 564 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/locales 565 | body: 566 | encoding: US-ASCII 567 | string: '' 568 | headers: 569 | User-Agent: 570 | - RubyContenfulManagementGem/0.1.0 571 | Authorization: 572 | - Bearer 573 | Content-Type: 574 | - application/vnd.contentful.management.v1+json 575 | Content-Length: 576 | - '0' 577 | Host: 578 | - api.contentful.com 579 | response: 580 | status: 581 | code: 200 582 | message: OK 583 | headers: 584 | "^access-Control-Expose-Headers": 585 | - Etag 586 | Accept-Ranges: 587 | - bytes 588 | Access-Control-Allow-Headers: 589 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 590 | Access-Control-Allow-Methods: 591 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 592 | Access-Control-Allow-Origin: 593 | - "*" 594 | Access-Control-Max-Age: 595 | - '1728000' 596 | Cache-Control: 597 | - max-age=0 598 | Content-Type: 599 | - application/vnd.contentful.management.v1+json 600 | Date: 601 | - Fri, 05 Sep 2014 11:38:09 GMT 602 | Etag: 603 | - '"30e7a28ed3dbfc3b90bc324b03fb16a8"' 604 | Server: 605 | - nginx 606 | Status: 607 | - 200 OK 608 | X-Contentful-Request-Id: 609 | - f1c-1376762769 610 | Content-Length: 611 | - '2619' 612 | Connection: 613 | - keep-alive 614 | body: 615 | encoding: UTF-8 616 | string: | 617 | { 618 | "sys":{ 619 | "type":"Array" 620 | }, 621 | "items":[ 622 | { 623 | "sys":{ 624 | "type":"Locale", 625 | "id":"3KpVOfIfikrLpwqCa49ami", 626 | "version":0, 627 | "space":{ 628 | "sys":{ 629 | "type":"Link", 630 | "linkType":"Space", 631 | "id":"v2umtz8ths9v" 632 | } 633 | }, 634 | "createdBy":{ 635 | "sys":{ 636 | "type":"Link", 637 | "linkType":"User", 638 | "id":"1E7acJL8I5XUXAMHQt9Grs" 639 | } 640 | }, 641 | "createdAt":"2014-08-21T13:32:12Z", 642 | "updatedBy":{ 643 | "sys":{ 644 | "type":"Link", 645 | "linkType":"User", 646 | "id":"1E7acJL8I5XUXAMHQt9Grs" 647 | } 648 | }, 649 | "updatedAt":"2014-08-21T13:32:12Z" 650 | }, 651 | "name":"U.S. English", 652 | "code":"en-US", 653 | "default":true, 654 | "contentManagementApi":true, 655 | "publish":true, 656 | "contentDeliveryApi":true 657 | }, 658 | { 659 | "sys":{ 660 | "type":"Locale", 661 | "id":"3PFj46pytOXQnNSEzqNsaO", 662 | "version":0, 663 | "space":{ 664 | "sys":{ 665 | "type":"Link", 666 | "linkType":"Space", 667 | "id":"v2umtz8ths9v" 668 | } 669 | }, 670 | "createdBy":{ 671 | "sys":{ 672 | "type":"Link", 673 | "linkType":"User", 674 | "id":"1E7acJL8I5XUXAMHQt9Grs" 675 | } 676 | }, 677 | "createdAt":"2014-08-21T13:32:16Z", 678 | "updatedBy":{ 679 | "sys":{ 680 | "type":"Link", 681 | "linkType":"User", 682 | "id":"1E7acJL8I5XUXAMHQt9Grs" 683 | } 684 | }, 685 | "updatedAt":"2014-08-21T13:32:16Z" 686 | }, 687 | "name":"German", 688 | "code":"de-DE", 689 | "default":false, 690 | "contentManagementApi":true, 691 | "publish":true, 692 | "contentDeliveryApi":true 693 | }, 694 | { 695 | "sys":{ 696 | "type":"Locale", 697 | "id":"3RN3vNgufcurpT9L5o8PBA", 698 | "version":0, 699 | "space":{ 700 | "sys":{ 701 | "type":"Link", 702 | "linkType":"Space", 703 | "id":"v2umtz8ths9v" 704 | } 705 | }, 706 | "createdBy":{ 707 | "sys":{ 708 | "type":"Link", 709 | "linkType":"User", 710 | "id":"1E7acJL8I5XUXAMHQt9Grs" 711 | } 712 | }, 713 | "createdAt":"2014-08-21T13:32:18Z", 714 | "updatedBy":{ 715 | "sys":{ 716 | "type":"Link", 717 | "linkType":"User", 718 | "id":"1E7acJL8I5XUXAMHQt9Grs" 719 | } 720 | }, 721 | "updatedAt":"2014-08-21T13:32:18Z" 722 | }, 723 | "name":"Polish", 724 | "code":"pl-PL", 725 | "default":false, 726 | "contentManagementApi":true, 727 | "publish":true, 728 | "contentDeliveryApi":true 729 | } 730 | ], 731 | "total":3, 732 | "limit":25, 733 | "skip":0} 734 | http_version: 735 | recorded_at: Fri, 05 Sep 2014 11:38:41 GMT 736 | - request: 737 | method: delete 738 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/entries/2TfOVAXdVYkMYuAsWsW8EW 739 | body: 740 | encoding: US-ASCII 741 | string: '' 742 | headers: 743 | User-Agent: 744 | - RubyContenfulManagementGem/0.1.0 745 | Authorization: 746 | - Bearer 747 | Content-Type: 748 | - application/vnd.contentful.management.v1+json 749 | Content-Length: 750 | - '0' 751 | Host: 752 | - api.contentful.com 753 | response: 754 | status: 755 | code: 204 756 | message: No Content 757 | headers: 758 | "^access-Control-Expose-Headers": 759 | - Etag 760 | Access-Control-Allow-Headers: 761 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 762 | Access-Control-Allow-Methods: 763 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 764 | Access-Control-Allow-Origin: 765 | - "*" 766 | Access-Control-Max-Age: 767 | - '1728000' 768 | Cf-Space-Id: 769 | - v2umtz8ths9v 770 | Content-Type: 771 | - application/vnd.contentful.management.v1+json 772 | Date: 773 | - Fri, 05 Sep 2014 11:38:10 GMT 774 | Server: 775 | - nginx 776 | X-Powered-By: 777 | - Express 778 | Connection: 779 | - keep-alive 780 | body: 781 | encoding: UTF-8 782 | string: '' 783 | http_version: 784 | recorded_at: Fri, 05 Sep 2014 11:38:42 GMT 785 | recorded_with: VCR 2.9.2 786 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/post/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.contentful.com/spaces/v2umtz8ths9v 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - RubyContenfulManagementGem/0.1.0 12 | Authorization: 13 | - Bearer 14 | Content-Type: 15 | - application/vnd.contentful.management.v1+json 16 | Content-Length: 17 | - '0' 18 | Host: 19 | - api.contentful.com 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | "^access-Control-Expose-Headers": 26 | - Etag 27 | Accept-Ranges: 28 | - bytes 29 | Access-Control-Allow-Headers: 30 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 31 | Access-Control-Allow-Methods: 32 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 33 | Access-Control-Allow-Origin: 34 | - "*" 35 | Access-Control-Max-Age: 36 | - '1728000' 37 | Cache-Control: 38 | - max-age=0 39 | Content-Type: 40 | - application/vnd.contentful.management.v1+json 41 | Date: 42 | - Fri, 05 Sep 2014 12:11:58 GMT 43 | Etag: 44 | - '"35407b8a88882fe5717a4701910f6ce7"' 45 | Server: 46 | - nginx 47 | Status: 48 | - 200 OK 49 | X-Contentful-Request-Id: 50 | - f1c-1376768946 51 | Content-Length: 52 | - '459' 53 | Connection: 54 | - keep-alive 55 | body: 56 | encoding: UTF-8 57 | string: | 58 | { 59 | "sys":{ 60 | "type":"Space", 61 | "id":"v2umtz8ths9v", 62 | "version":1, 63 | "createdBy":{ 64 | "sys":{ 65 | "type":"Link", 66 | "linkType":"User", 67 | "id":"1E7acJL8I5XUXAMHQt9Grs" 68 | } 69 | }, 70 | "createdAt":"2014-08-21T13:32:11Z", 71 | "updatedBy":{ 72 | "sys":{ 73 | "type":"Link", 74 | "linkType":"User", 75 | "id":"1E7acJL8I5XUXAMHQt9Grs" 76 | } 77 | }, 78 | "updatedAt":"2014-08-21T13:32:12Z" 79 | }, 80 | "name":"CMA Demo Rails App"} 81 | http_version: 82 | recorded_at: Fri, 05 Sep 2014 12:12:29 GMT 83 | - request: 84 | method: get 85 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types 86 | body: 87 | encoding: US-ASCII 88 | string: '' 89 | headers: 90 | User-Agent: 91 | - RubyContenfulManagementGem/0.1.0 92 | Authorization: 93 | - Bearer 94 | Content-Type: 95 | - application/vnd.contentful.management.v1+json 96 | Content-Length: 97 | - '0' 98 | Host: 99 | - api.contentful.com 100 | response: 101 | status: 102 | code: 200 103 | message: OK 104 | headers: 105 | "^access-Control-Expose-Headers": 106 | - Etag 107 | Access-Control-Allow-Headers: 108 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 109 | Access-Control-Allow-Methods: 110 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 111 | Access-Control-Allow-Origin: 112 | - "*" 113 | Access-Control-Max-Age: 114 | - '1728000' 115 | Cf-Space-Id: 116 | - v2umtz8ths9v 117 | Content-Type: 118 | - application/vnd.contentful.management.v1+json 119 | Date: 120 | - Fri, 05 Sep 2014 12:11:58 GMT 121 | Etag: 122 | - '"2a8abfd957b4ad9b6b47f853bd58078a"' 123 | Server: 124 | - nginx 125 | X-Powered-By: 126 | - Express 127 | Content-Length: 128 | - '5193' 129 | Connection: 130 | - keep-alive 131 | body: 132 | encoding: UTF-8 133 | string: | 134 | { 135 | "sys": { 136 | "type": "Array" 137 | }, 138 | "total": 3, 139 | "skip": 0, 140 | "limit": 100, 141 | "items": [ 142 | { 143 | "fields": [ 144 | { 145 | "name": "testowe", 146 | "id": "testowe", 147 | "type": "Link", 148 | "uiid": "3q907mcb4lc", 149 | "linkType": "Asset", 150 | "required": true, 151 | "localized": true 152 | } 153 | ], 154 | "name": "test", 155 | "sys": { 156 | "id": "26eLfV14SIOeQkse44q4sw", 157 | "type": "ContentType", 158 | "createdAt": "2014-08-22T12:57:43.618Z", 159 | "createdBy": { 160 | "sys": { 161 | "type": "Link", 162 | "linkType": "User", 163 | "id": "1E7acJL8I5XUXAMHQt9Grs" 164 | } 165 | }, 166 | "space": { 167 | "sys": { 168 | "type": "Link", 169 | "linkType": "Space", 170 | "id": "v2umtz8ths9v" 171 | } 172 | }, 173 | "firstPublishedAt": "2014-08-22T12:57:53.093Z", 174 | "publishedCounter": 2, 175 | "publishedAt": "2014-08-22T12:57:58.628Z", 176 | "publishedBy": { 177 | "sys": { 178 | "type": "Link", 179 | "linkType": "User", 180 | "id": "1E7acJL8I5XUXAMHQt9Grs" 181 | } 182 | }, 183 | "publishedVersion": 13, 184 | "version": 14, 185 | "updatedAt": "2014-08-22T12:57:58.633Z", 186 | "updatedBy": { 187 | "sys": { 188 | "type": "Link", 189 | "linkType": "User", 190 | "id": "1E7acJL8I5XUXAMHQt9Grs" 191 | } 192 | } 193 | } 194 | }, 195 | { 196 | "displayField": "title", 197 | "name": "Post", 198 | "description": "", 199 | "fields": [ 200 | { 201 | "id": "title", 202 | "name": "Title", 203 | "type": "Text", 204 | "localized": true, 205 | "uiid": "2sdir2f8kcg" 206 | }, 207 | { 208 | "id": "author", 209 | "name": "Author", 210 | "type": "Text", 211 | "localized": true, 212 | "uiid": "4x1018907pc" 213 | }, 214 | { 215 | "id": "body", 216 | "name": "Body", 217 | "type": "Text", 218 | "localized": true, 219 | "uiid": "4hj7cda89hc" 220 | }, 221 | { 222 | "id": "title_image", 223 | "name": "Title Image", 224 | "type": "Link", 225 | "linkType": "Asset", 226 | "required": true, 227 | "localized": true, 228 | "uiid": "4gcqrcma8lc" 229 | }, 230 | { 231 | "id": "second_image", 232 | "name": "Second Image", 233 | "type": "Link", 234 | "linkType": "Asset", 235 | "localized": true, 236 | "uiid": "40440elrugw" 237 | }, 238 | { 239 | "id": "category", 240 | "name": "Category", 241 | "type": "Link", 242 | "linkType": "Entry", 243 | "uiid": "49vicjvqsxs", 244 | "localized": true 245 | } 246 | ], 247 | "sys": { 248 | "id": "post_content_type", 249 | "type": "ContentType", 250 | "createdAt": "2014-08-21T13:32:30.401Z", 251 | "createdBy": { 252 | "sys": { 253 | "type": "Link", 254 | "linkType": "User", 255 | "id": "1E7acJL8I5XUXAMHQt9Grs" 256 | } 257 | }, 258 | "space": { 259 | "sys": { 260 | "type": "Link", 261 | "linkType": "Space", 262 | "id": "v2umtz8ths9v" 263 | } 264 | }, 265 | "firstPublishedAt": "2014-08-21T13:32:43.385Z", 266 | "publishedCounter": 2, 267 | "publishedAt": "2014-08-27T09:18:36.995Z", 268 | "publishedBy": { 269 | "sys": { 270 | "type": "Link", 271 | "linkType": "User", 272 | "id": "1E7acJL8I5XUXAMHQt9Grs" 273 | } 274 | }, 275 | "publishedVersion": 11, 276 | "version": 12, 277 | "updatedAt": "2014-08-27T09:18:37.003Z", 278 | "updatedBy": { 279 | "sys": { 280 | "type": "Link", 281 | "linkType": "User", 282 | "id": "1E7acJL8I5XUXAMHQt9Grs" 283 | } 284 | } 285 | } 286 | }, 287 | { 288 | "displayField": "name", 289 | "name": "Category", 290 | "description": "", 291 | "fields": [ 292 | { 293 | "id": "name", 294 | "name": "Name", 295 | "type": "Text", 296 | "localized": true, 297 | "uiid": "3ic0t3qi51c" 298 | }, 299 | { 300 | "id": "description", 301 | "name": "Description", 302 | "type": "Text", 303 | "localized": false, 304 | "uiid": "38xiq8fobnk" 305 | } 306 | ], 307 | "sys": { 308 | "id": "category_content_type", 309 | "type": "ContentType", 310 | "createdAt": "2014-08-21T13:32:20.955Z", 311 | "createdBy": { 312 | "sys": { 313 | "type": "Link", 314 | "linkType": "User", 315 | "id": "1E7acJL8I5XUXAMHQt9Grs" 316 | } 317 | }, 318 | "space": { 319 | "sys": { 320 | "type": "Link", 321 | "linkType": "Space", 322 | "id": "v2umtz8ths9v" 323 | } 324 | }, 325 | "firstPublishedAt": "2014-08-21T13:32:27.109Z", 326 | "publishedCounter": 8, 327 | "publishedAt": "2014-09-04T18:02:17.407Z", 328 | "publishedBy": { 329 | "sys": { 330 | "type": "Link", 331 | "linkType": "User", 332 | "id": "1E7acJL8I5XUXAMHQt9Grs" 333 | } 334 | }, 335 | "publishedVersion": 31, 336 | "version": 32, 337 | "updatedAt": "2014-09-04T18:02:17.415Z", 338 | "updatedBy": { 339 | "sys": { 340 | "type": "Link", 341 | "linkType": "User", 342 | "id": "1E7acJL8I5XUXAMHQt9Grs" 343 | } 344 | } 345 | } 346 | } 347 | ] 348 | } 349 | http_version: 350 | recorded_at: Fri, 05 Sep 2014 12:12:30 GMT 351 | - request: 352 | method: get 353 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/entries/3b5W5MAuX6gYi0EquAWCas 354 | body: 355 | encoding: US-ASCII 356 | string: '' 357 | headers: 358 | User-Agent: 359 | - RubyContenfulManagementGem/0.1.0 360 | Authorization: 361 | - Bearer 362 | Content-Type: 363 | - application/vnd.contentful.management.v1+json 364 | Content-Length: 365 | - '0' 366 | Host: 367 | - api.contentful.com 368 | response: 369 | status: 370 | code: 200 371 | message: OK 372 | headers: 373 | "^access-Control-Expose-Headers": 374 | - Etag 375 | Access-Control-Allow-Headers: 376 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 377 | Access-Control-Allow-Methods: 378 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 379 | Access-Control-Allow-Origin: 380 | - "*" 381 | Access-Control-Max-Age: 382 | - '1728000' 383 | Cf-Space-Id: 384 | - v2umtz8ths9v 385 | Content-Type: 386 | - application/vnd.contentful.management.v1+json 387 | Date: 388 | - Fri, 05 Sep 2014 12:11:59 GMT 389 | Etag: 390 | - '"33b7432149492b0e3f6e6fb4d4686586"' 391 | Server: 392 | - nginx 393 | X-Powered-By: 394 | - Express 395 | Content-Length: 396 | - '734' 397 | Connection: 398 | - keep-alive 399 | body: 400 | encoding: UTF-8 401 | string: | 402 | { 403 | "sys": { 404 | "id": "3b5W5MAuX6gYi0EquAWCas", 405 | "type": "Entry", 406 | "createdAt": "2014-09-05T12:11:42.227Z", 407 | "createdBy": { 408 | "sys": { 409 | "type": "Link", 410 | "linkType": "User", 411 | "id": "1E7acJL8I5XUXAMHQt9Grs" 412 | } 413 | }, 414 | "space": { 415 | "sys": { 416 | "type": "Link", 417 | "linkType": "Space", 418 | "id": "v2umtz8ths9v" 419 | } 420 | }, 421 | "contentType": { 422 | "sys": { 423 | "type": "Link", 424 | "linkType": "ContentType", 425 | "id": "post_content_type" 426 | } 427 | }, 428 | "version": 1, 429 | "updatedAt": "2014-09-05T12:11:42.230Z", 430 | "updatedBy": { 431 | "sys": { 432 | "type": "Link", 433 | "linkType": "User", 434 | "id": "1E7acJL8I5XUXAMHQt9Grs" 435 | } 436 | } 437 | } 438 | } 439 | http_version: 440 | recorded_at: Fri, 05 Sep 2014 12:12:30 GMT 441 | - request: 442 | method: get 443 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types/post_content_type 444 | body: 445 | encoding: US-ASCII 446 | string: '' 447 | headers: 448 | User-Agent: 449 | - RubyContenfulManagementGem/0.1.0 450 | Authorization: 451 | - Bearer 452 | Content-Type: 453 | - application/vnd.contentful.management.v1+json 454 | Content-Length: 455 | - '0' 456 | Host: 457 | - api.contentful.com 458 | response: 459 | status: 460 | code: 200 461 | message: OK 462 | headers: 463 | "^access-Control-Expose-Headers": 464 | - Etag 465 | Access-Control-Allow-Headers: 466 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 467 | Access-Control-Allow-Methods: 468 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 469 | Access-Control-Allow-Origin: 470 | - "*" 471 | Access-Control-Max-Age: 472 | - '1728000' 473 | Cf-Space-Id: 474 | - v2umtz8ths9v 475 | Content-Type: 476 | - application/vnd.contentful.management.v1+json 477 | Date: 478 | - Fri, 05 Sep 2014 12:11:59 GMT 479 | Etag: 480 | - '"00bbe1be51263a5c25e4459a8f1cda3c"' 481 | Server: 482 | - nginx 483 | X-Powered-By: 484 | - Express 485 | Content-Length: 486 | - '1901' 487 | Connection: 488 | - keep-alive 489 | body: 490 | encoding: UTF-8 491 | string: | 492 | { 493 | "displayField": "title", 494 | "name": "Post", 495 | "description": "", 496 | "fields": [ 497 | { 498 | "id": "title", 499 | "name": "Title", 500 | "type": "Text", 501 | "localized": true, 502 | "uiid": "2sdir2f8kcg" 503 | }, 504 | { 505 | "id": "author", 506 | "name": "Author", 507 | "type": "Text", 508 | "localized": true, 509 | "uiid": "4x1018907pc" 510 | }, 511 | { 512 | "id": "body", 513 | "name": "Body", 514 | "type": "Text", 515 | "localized": true, 516 | "uiid": "4hj7cda89hc" 517 | }, 518 | { 519 | "id": "title_image", 520 | "name": "Title Image", 521 | "type": "Link", 522 | "linkType": "Asset", 523 | "required": true, 524 | "localized": true, 525 | "uiid": "4gcqrcma8lc" 526 | }, 527 | { 528 | "id": "second_image", 529 | "name": "Second Image", 530 | "type": "Link", 531 | "linkType": "Asset", 532 | "localized": true, 533 | "uiid": "40440elrugw" 534 | }, 535 | { 536 | "id": "category", 537 | "name": "Category", 538 | "type": "Link", 539 | "linkType": "Entry", 540 | "uiid": "49vicjvqsxs", 541 | "localized": true 542 | } 543 | ], 544 | "sys": { 545 | "id": "post_content_type", 546 | "type": "ContentType", 547 | "createdAt": "2014-08-21T13:32:30.401Z", 548 | "createdBy": { 549 | "sys": { 550 | "type": "Link", 551 | "linkType": "User", 552 | "id": "1E7acJL8I5XUXAMHQt9Grs" 553 | } 554 | }, 555 | "space": { 556 | "sys": { 557 | "type": "Link", 558 | "linkType": "Space", 559 | "id": "v2umtz8ths9v" 560 | } 561 | }, 562 | "firstPublishedAt": "2014-08-21T13:32:43.385Z", 563 | "publishedCounter": 2, 564 | "publishedAt": "2014-08-27T09:18:36.995Z", 565 | "publishedBy": { 566 | "sys": { 567 | "type": "Link", 568 | "linkType": "User", 569 | "id": "1E7acJL8I5XUXAMHQt9Grs" 570 | } 571 | }, 572 | "publishedVersion": 11, 573 | "version": 12, 574 | "updatedAt": "2014-08-27T09:18:37.003Z", 575 | "updatedBy": { 576 | "sys": { 577 | "type": "Link", 578 | "linkType": "User", 579 | "id": "1E7acJL8I5XUXAMHQt9Grs" 580 | } 581 | } 582 | } 583 | } 584 | http_version: 585 | recorded_at: Fri, 05 Sep 2014 12:12:31 GMT 586 | - request: 587 | method: get 588 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/locales 589 | body: 590 | encoding: US-ASCII 591 | string: '' 592 | headers: 593 | User-Agent: 594 | - RubyContenfulManagementGem/0.1.0 595 | Authorization: 596 | - Bearer 597 | Content-Type: 598 | - application/vnd.contentful.management.v1+json 599 | Content-Length: 600 | - '0' 601 | Host: 602 | - api.contentful.com 603 | response: 604 | status: 605 | code: 200 606 | message: OK 607 | headers: 608 | "^access-Control-Expose-Headers": 609 | - Etag 610 | Accept-Ranges: 611 | - bytes 612 | Access-Control-Allow-Headers: 613 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 614 | Access-Control-Allow-Methods: 615 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 616 | Access-Control-Allow-Origin: 617 | - "*" 618 | Access-Control-Max-Age: 619 | - '1728000' 620 | Cache-Control: 621 | - max-age=0 622 | Content-Type: 623 | - application/vnd.contentful.management.v1+json 624 | Date: 625 | - Fri, 05 Sep 2014 12:12:00 GMT 626 | Etag: 627 | - '"30e7a28ed3dbfc3b90bc324b03fb16a8"' 628 | Server: 629 | - nginx 630 | Status: 631 | - 200 OK 632 | X-Contentful-Request-Id: 633 | - 85f-935741156 634 | Content-Length: 635 | - '2619' 636 | Connection: 637 | - keep-alive 638 | body: 639 | encoding: UTF-8 640 | string: | 641 | { 642 | "sys":{ 643 | "type":"Array" 644 | }, 645 | "items":[ 646 | { 647 | "sys":{ 648 | "type":"Locale", 649 | "id":"3KpVOfIfikrLpwqCa49ami", 650 | "version":0, 651 | "space":{ 652 | "sys":{ 653 | "type":"Link", 654 | "linkType":"Space", 655 | "id":"v2umtz8ths9v" 656 | } 657 | }, 658 | "createdBy":{ 659 | "sys":{ 660 | "type":"Link", 661 | "linkType":"User", 662 | "id":"1E7acJL8I5XUXAMHQt9Grs" 663 | } 664 | }, 665 | "createdAt":"2014-08-21T13:32:12Z", 666 | "updatedBy":{ 667 | "sys":{ 668 | "type":"Link", 669 | "linkType":"User", 670 | "id":"1E7acJL8I5XUXAMHQt9Grs" 671 | } 672 | }, 673 | "updatedAt":"2014-08-21T13:32:12Z" 674 | }, 675 | "name":"U.S. English", 676 | "code":"en-US", 677 | "default":true, 678 | "contentManagementApi":true, 679 | "publish":true, 680 | "contentDeliveryApi":true 681 | }, 682 | { 683 | "sys":{ 684 | "type":"Locale", 685 | "id":"3PFj46pytOXQnNSEzqNsaO", 686 | "version":0, 687 | "space":{ 688 | "sys":{ 689 | "type":"Link", 690 | "linkType":"Space", 691 | "id":"v2umtz8ths9v" 692 | } 693 | }, 694 | "createdBy":{ 695 | "sys":{ 696 | "type":"Link", 697 | "linkType":"User", 698 | "id":"1E7acJL8I5XUXAMHQt9Grs" 699 | } 700 | }, 701 | "createdAt":"2014-08-21T13:32:16Z", 702 | "updatedBy":{ 703 | "sys":{ 704 | "type":"Link", 705 | "linkType":"User", 706 | "id":"1E7acJL8I5XUXAMHQt9Grs" 707 | } 708 | }, 709 | "updatedAt":"2014-08-21T13:32:16Z" 710 | }, 711 | "name":"German", 712 | "code":"de-DE", 713 | "default":false, 714 | "contentManagementApi":true, 715 | "publish":true, 716 | "contentDeliveryApi":true 717 | }, 718 | { 719 | "sys":{ 720 | "type":"Locale", 721 | "id":"3RN3vNgufcurpT9L5o8PBA", 722 | "version":0, 723 | "space":{ 724 | "sys":{ 725 | "type":"Link", 726 | "linkType":"Space", 727 | "id":"v2umtz8ths9v" 728 | } 729 | }, 730 | "createdBy":{ 731 | "sys":{ 732 | "type":"Link", 733 | "linkType":"User", 734 | "id":"1E7acJL8I5XUXAMHQt9Grs" 735 | } 736 | }, 737 | "createdAt":"2014-08-21T13:32:18Z", 738 | "updatedBy":{ 739 | "sys":{ 740 | "type":"Link", 741 | "linkType":"User", 742 | "id":"1E7acJL8I5XUXAMHQt9Grs" 743 | } 744 | }, 745 | "updatedAt":"2014-08-21T13:32:18Z" 746 | }, 747 | "name":"Polish", 748 | "code":"pl-PL", 749 | "default":false, 750 | "contentManagementApi":true, 751 | "publish":true, 752 | "contentDeliveryApi":true 753 | } 754 | ], 755 | "total":3, 756 | "limit":25, 757 | "skip":0} 758 | http_version: 759 | recorded_at: Fri, 05 Sep 2014 12:12:31 GMT 760 | - request: 761 | method: delete 762 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/entries/3b5W5MAuX6gYi0EquAWCas 763 | body: 764 | encoding: US-ASCII 765 | string: '' 766 | headers: 767 | User-Agent: 768 | - RubyContenfulManagementGem/0.1.0 769 | Authorization: 770 | - Bearer 771 | Content-Type: 772 | - application/vnd.contentful.management.v1+json 773 | Content-Length: 774 | - '0' 775 | Host: 776 | - api.contentful.com 777 | response: 778 | status: 779 | code: 204 780 | message: No Content 781 | headers: 782 | "^access-Control-Expose-Headers": 783 | - Etag 784 | Access-Control-Allow-Headers: 785 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 786 | Access-Control-Allow-Methods: 787 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 788 | Access-Control-Allow-Origin: 789 | - "*" 790 | Access-Control-Max-Age: 791 | - '1728000' 792 | Cf-Space-Id: 793 | - v2umtz8ths9v 794 | Content-Type: 795 | - application/vnd.contentful.management.v1+json 796 | Date: 797 | - Fri, 05 Sep 2014 12:12:01 GMT 798 | Server: 799 | - nginx 800 | X-Powered-By: 801 | - Express 802 | Connection: 803 | - keep-alive 804 | body: 805 | encoding: UTF-8 806 | string: '' 807 | http_version: 808 | recorded_at: Fri, 05 Sep 2014 12:12:32 GMT 809 | recorded_with: VCR 2.9.2 810 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/category/update.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.contentful.com/spaces/v2umtz8ths9v 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - RubyContenfulManagementGem/0.1.0 12 | Authorization: 13 | - Bearer 14 | Content-Type: 15 | - application/vnd.contentful.management.v1+json 16 | Content-Length: 17 | - '0' 18 | Host: 19 | - api.contentful.com 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | "^access-Control-Expose-Headers": 26 | - Etag 27 | Accept-Ranges: 28 | - bytes 29 | Access-Control-Allow-Headers: 30 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 31 | Access-Control-Allow-Methods: 32 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 33 | Access-Control-Allow-Origin: 34 | - "*" 35 | Access-Control-Max-Age: 36 | - '1728000' 37 | Cache-Control: 38 | - max-age=0 39 | Content-Type: 40 | - application/vnd.contentful.management.v1+json 41 | Date: 42 | - Fri, 05 Sep 2014 11:39:51 GMT 43 | Etag: 44 | - '"35407b8a88882fe5717a4701910f6ce7"' 45 | Server: 46 | - nginx 47 | Status: 48 | - 200 OK 49 | X-Contentful-Request-Id: 50 | - f1c-1376763019 51 | Content-Length: 52 | - '459' 53 | Connection: 54 | - keep-alive 55 | body: 56 | encoding: UTF-8 57 | string: | 58 | { 59 | "sys":{ 60 | "type":"Space", 61 | "id":"v2umtz8ths9v", 62 | "version":1, 63 | "createdBy":{ 64 | "sys":{ 65 | "type":"Link", 66 | "linkType":"User", 67 | "id":"1E7acJL8I5XUXAMHQt9Grs" 68 | } 69 | }, 70 | "createdAt":"2014-08-21T13:32:11Z", 71 | "updatedBy":{ 72 | "sys":{ 73 | "type":"Link", 74 | "linkType":"User", 75 | "id":"1E7acJL8I5XUXAMHQt9Grs" 76 | } 77 | }, 78 | "updatedAt":"2014-08-21T13:32:12Z" 79 | }, 80 | "name":"CMA Demo Rails App"} 81 | http_version: 82 | recorded_at: Fri, 05 Sep 2014 11:40:23 GMT 83 | - request: 84 | method: get 85 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types 86 | body: 87 | encoding: US-ASCII 88 | string: '' 89 | headers: 90 | User-Agent: 91 | - RubyContenfulManagementGem/0.1.0 92 | Authorization: 93 | - Bearer 94 | Content-Type: 95 | - application/vnd.contentful.management.v1+json 96 | Content-Length: 97 | - '0' 98 | Host: 99 | - api.contentful.com 100 | response: 101 | status: 102 | code: 200 103 | message: OK 104 | headers: 105 | "^access-Control-Expose-Headers": 106 | - Etag 107 | Access-Control-Allow-Headers: 108 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 109 | Access-Control-Allow-Methods: 110 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 111 | Access-Control-Allow-Origin: 112 | - "*" 113 | Access-Control-Max-Age: 114 | - '1728000' 115 | Cf-Space-Id: 116 | - v2umtz8ths9v 117 | Content-Type: 118 | - application/vnd.contentful.management.v1+json 119 | Date: 120 | - Fri, 05 Sep 2014 11:39:51 GMT 121 | Etag: 122 | - '"2a8abfd957b4ad9b6b47f853bd58078a"' 123 | Server: 124 | - nginx 125 | X-Powered-By: 126 | - Express 127 | Content-Length: 128 | - '5193' 129 | Connection: 130 | - keep-alive 131 | body: 132 | encoding: UTF-8 133 | string: | 134 | { 135 | "sys": { 136 | "type": "Array" 137 | }, 138 | "total": 3, 139 | "skip": 0, 140 | "limit": 100, 141 | "items": [ 142 | { 143 | "fields": [ 144 | { 145 | "name": "testowe", 146 | "id": "testowe", 147 | "type": "Link", 148 | "uiid": "3q907mcb4lc", 149 | "linkType": "Asset", 150 | "required": true, 151 | "localized": true 152 | } 153 | ], 154 | "name": "test", 155 | "sys": { 156 | "id": "26eLfV14SIOeQkse44q4sw", 157 | "type": "ContentType", 158 | "createdAt": "2014-08-22T12:57:43.618Z", 159 | "createdBy": { 160 | "sys": { 161 | "type": "Link", 162 | "linkType": "User", 163 | "id": "1E7acJL8I5XUXAMHQt9Grs" 164 | } 165 | }, 166 | "space": { 167 | "sys": { 168 | "type": "Link", 169 | "linkType": "Space", 170 | "id": "v2umtz8ths9v" 171 | } 172 | }, 173 | "firstPublishedAt": "2014-08-22T12:57:53.093Z", 174 | "publishedCounter": 2, 175 | "publishedAt": "2014-08-22T12:57:58.628Z", 176 | "publishedBy": { 177 | "sys": { 178 | "type": "Link", 179 | "linkType": "User", 180 | "id": "1E7acJL8I5XUXAMHQt9Grs" 181 | } 182 | }, 183 | "publishedVersion": 13, 184 | "version": 14, 185 | "updatedAt": "2014-08-22T12:57:58.633Z", 186 | "updatedBy": { 187 | "sys": { 188 | "type": "Link", 189 | "linkType": "User", 190 | "id": "1E7acJL8I5XUXAMHQt9Grs" 191 | } 192 | } 193 | } 194 | }, 195 | { 196 | "displayField": "title", 197 | "name": "Post", 198 | "description": "", 199 | "fields": [ 200 | { 201 | "id": "title", 202 | "name": "Title", 203 | "type": "Text", 204 | "localized": true, 205 | "uiid": "2sdir2f8kcg" 206 | }, 207 | { 208 | "id": "author", 209 | "name": "Author", 210 | "type": "Text", 211 | "localized": true, 212 | "uiid": "4x1018907pc" 213 | }, 214 | { 215 | "id": "body", 216 | "name": "Body", 217 | "type": "Text", 218 | "localized": true, 219 | "uiid": "4hj7cda89hc" 220 | }, 221 | { 222 | "id": "title_image", 223 | "name": "Title Image", 224 | "type": "Link", 225 | "linkType": "Asset", 226 | "required": true, 227 | "localized": true, 228 | "uiid": "4gcqrcma8lc" 229 | }, 230 | { 231 | "id": "second_image", 232 | "name": "Second Image", 233 | "type": "Link", 234 | "linkType": "Asset", 235 | "localized": true, 236 | "uiid": "40440elrugw" 237 | }, 238 | { 239 | "id": "category", 240 | "name": "Category", 241 | "type": "Link", 242 | "linkType": "Entry", 243 | "uiid": "49vicjvqsxs", 244 | "localized": true 245 | } 246 | ], 247 | "sys": { 248 | "id": "post_content_type", 249 | "type": "ContentType", 250 | "createdAt": "2014-08-21T13:32:30.401Z", 251 | "createdBy": { 252 | "sys": { 253 | "type": "Link", 254 | "linkType": "User", 255 | "id": "1E7acJL8I5XUXAMHQt9Grs" 256 | } 257 | }, 258 | "space": { 259 | "sys": { 260 | "type": "Link", 261 | "linkType": "Space", 262 | "id": "v2umtz8ths9v" 263 | } 264 | }, 265 | "firstPublishedAt": "2014-08-21T13:32:43.385Z", 266 | "publishedCounter": 2, 267 | "publishedAt": "2014-08-27T09:18:36.995Z", 268 | "publishedBy": { 269 | "sys": { 270 | "type": "Link", 271 | "linkType": "User", 272 | "id": "1E7acJL8I5XUXAMHQt9Grs" 273 | } 274 | }, 275 | "publishedVersion": 11, 276 | "version": 12, 277 | "updatedAt": "2014-08-27T09:18:37.003Z", 278 | "updatedBy": { 279 | "sys": { 280 | "type": "Link", 281 | "linkType": "User", 282 | "id": "1E7acJL8I5XUXAMHQt9Grs" 283 | } 284 | } 285 | } 286 | }, 287 | { 288 | "displayField": "name", 289 | "name": "Category", 290 | "description": "", 291 | "fields": [ 292 | { 293 | "id": "name", 294 | "name": "Name", 295 | "type": "Text", 296 | "localized": true, 297 | "uiid": "3ic0t3qi51c" 298 | }, 299 | { 300 | "id": "description", 301 | "name": "Description", 302 | "type": "Text", 303 | "localized": false, 304 | "uiid": "38xiq8fobnk" 305 | } 306 | ], 307 | "sys": { 308 | "id": "category_content_type", 309 | "type": "ContentType", 310 | "createdAt": "2014-08-21T13:32:20.955Z", 311 | "createdBy": { 312 | "sys": { 313 | "type": "Link", 314 | "linkType": "User", 315 | "id": "1E7acJL8I5XUXAMHQt9Grs" 316 | } 317 | }, 318 | "space": { 319 | "sys": { 320 | "type": "Link", 321 | "linkType": "Space", 322 | "id": "v2umtz8ths9v" 323 | } 324 | }, 325 | "firstPublishedAt": "2014-08-21T13:32:27.109Z", 326 | "publishedCounter": 8, 327 | "publishedAt": "2014-09-04T18:02:17.407Z", 328 | "publishedBy": { 329 | "sys": { 330 | "type": "Link", 331 | "linkType": "User", 332 | "id": "1E7acJL8I5XUXAMHQt9Grs" 333 | } 334 | }, 335 | "publishedVersion": 31, 336 | "version": 32, 337 | "updatedAt": "2014-09-04T18:02:17.415Z", 338 | "updatedBy": { 339 | "sys": { 340 | "type": "Link", 341 | "linkType": "User", 342 | "id": "1E7acJL8I5XUXAMHQt9Grs" 343 | } 344 | } 345 | } 346 | } 347 | ] 348 | } 349 | http_version: 350 | recorded_at: Fri, 05 Sep 2014 11:40:24 GMT 351 | - request: 352 | method: get 353 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/entries/14498XWGiIwQyOAmKq2YeO 354 | body: 355 | encoding: US-ASCII 356 | string: '' 357 | headers: 358 | User-Agent: 359 | - RubyContenfulManagementGem/0.1.0 360 | Authorization: 361 | - Bearer 362 | Content-Type: 363 | - application/vnd.contentful.management.v1+json 364 | Content-Length: 365 | - '0' 366 | Host: 367 | - api.contentful.com 368 | response: 369 | status: 370 | code: 200 371 | message: OK 372 | headers: 373 | "^access-Control-Expose-Headers": 374 | - Etag 375 | Access-Control-Allow-Headers: 376 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 377 | Access-Control-Allow-Methods: 378 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 379 | Access-Control-Allow-Origin: 380 | - "*" 381 | Access-Control-Max-Age: 382 | - '1728000' 383 | Cf-Space-Id: 384 | - v2umtz8ths9v 385 | Content-Type: 386 | - application/vnd.contentful.management.v1+json 387 | Date: 388 | - Fri, 05 Sep 2014 11:39:52 GMT 389 | Etag: 390 | - '"1c6fe28b61eecb48987bc0f460e17366"' 391 | Server: 392 | - nginx 393 | X-Powered-By: 394 | - Express 395 | Content-Length: 396 | - '931' 397 | Connection: 398 | - keep-alive 399 | body: 400 | encoding: UTF-8 401 | string: | 402 | { 403 | "fields": { 404 | "name": { 405 | "en-US": "Sports EN x", 406 | "de-DE": "Sport DE x", 407 | "pl-PL": "Sport PL x " 408 | }, 409 | "description": { 410 | "en-US": "Sports category EN x" 411 | } 412 | }, 413 | "sys": { 414 | "id": "14498XWGiIwQyOAmKq2YeO", 415 | "type": "Entry", 416 | "createdAt": "2014-09-04T18:03:24.057Z", 417 | "createdBy": { 418 | "sys": { 419 | "type": "Link", 420 | "linkType": "User", 421 | "id": "1E7acJL8I5XUXAMHQt9Grs" 422 | } 423 | }, 424 | "space": { 425 | "sys": { 426 | "type": "Link", 427 | "linkType": "Space", 428 | "id": "v2umtz8ths9v" 429 | } 430 | }, 431 | "contentType": { 432 | "sys": { 433 | "type": "Link", 434 | "linkType": "ContentType", 435 | "id": "category_content_type" 436 | } 437 | }, 438 | "version": 2, 439 | "updatedAt": "2014-09-04T18:06:02.404Z", 440 | "updatedBy": { 441 | "sys": { 442 | "type": "Link", 443 | "linkType": "User", 444 | "id": "1E7acJL8I5XUXAMHQt9Grs" 445 | } 446 | } 447 | } 448 | } 449 | http_version: 450 | recorded_at: Fri, 05 Sep 2014 11:40:24 GMT 451 | - request: 452 | method: get 453 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/content_types/category_content_type 454 | body: 455 | encoding: US-ASCII 456 | string: '' 457 | headers: 458 | User-Agent: 459 | - RubyContenfulManagementGem/0.1.0 460 | Authorization: 461 | - Bearer 462 | Content-Type: 463 | - application/vnd.contentful.management.v1+json 464 | Content-Length: 465 | - '0' 466 | Host: 467 | - api.contentful.com 468 | response: 469 | status: 470 | code: 200 471 | message: OK 472 | headers: 473 | "^access-Control-Expose-Headers": 474 | - Etag 475 | Access-Control-Allow-Headers: 476 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 477 | Access-Control-Allow-Methods: 478 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 479 | Access-Control-Allow-Origin: 480 | - "*" 481 | Access-Control-Max-Age: 482 | - '1728000' 483 | Cf-Space-Id: 484 | - v2umtz8ths9v 485 | Content-Type: 486 | - application/vnd.contentful.management.v1+json 487 | Date: 488 | - Fri, 05 Sep 2014 11:39:52 GMT 489 | Etag: 490 | - '"46343a08da081aa9a2276b139329768d"' 491 | Server: 492 | - nginx 493 | X-Powered-By: 494 | - Express 495 | Content-Length: 496 | - '1254' 497 | Connection: 498 | - keep-alive 499 | body: 500 | encoding: UTF-8 501 | string: | 502 | { 503 | "displayField": "name", 504 | "name": "Category", 505 | "description": "", 506 | "fields": [ 507 | { 508 | "id": "name", 509 | "name": "Name", 510 | "type": "Text", 511 | "localized": true, 512 | "uiid": "3ic0t3qi51c" 513 | }, 514 | { 515 | "id": "description", 516 | "name": "Description", 517 | "type": "Text", 518 | "localized": false, 519 | "uiid": "38xiq8fobnk" 520 | } 521 | ], 522 | "sys": { 523 | "id": "category_content_type", 524 | "type": "ContentType", 525 | "createdAt": "2014-08-21T13:32:20.955Z", 526 | "createdBy": { 527 | "sys": { 528 | "type": "Link", 529 | "linkType": "User", 530 | "id": "1E7acJL8I5XUXAMHQt9Grs" 531 | } 532 | }, 533 | "space": { 534 | "sys": { 535 | "type": "Link", 536 | "linkType": "Space", 537 | "id": "v2umtz8ths9v" 538 | } 539 | }, 540 | "firstPublishedAt": "2014-08-21T13:32:27.109Z", 541 | "publishedCounter": 8, 542 | "publishedAt": "2014-09-04T18:02:17.407Z", 543 | "publishedBy": { 544 | "sys": { 545 | "type": "Link", 546 | "linkType": "User", 547 | "id": "1E7acJL8I5XUXAMHQt9Grs" 548 | } 549 | }, 550 | "publishedVersion": 31, 551 | "version": 32, 552 | "updatedAt": "2014-09-04T18:02:17.415Z", 553 | "updatedBy": { 554 | "sys": { 555 | "type": "Link", 556 | "linkType": "User", 557 | "id": "1E7acJL8I5XUXAMHQt9Grs" 558 | } 559 | } 560 | } 561 | } 562 | http_version: 563 | recorded_at: Fri, 05 Sep 2014 11:40:25 GMT 564 | - request: 565 | method: get 566 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/locales 567 | body: 568 | encoding: US-ASCII 569 | string: '' 570 | headers: 571 | User-Agent: 572 | - RubyContenfulManagementGem/0.1.0 573 | Authorization: 574 | - Bearer 575 | Content-Type: 576 | - application/vnd.contentful.management.v1+json 577 | Content-Length: 578 | - '0' 579 | Host: 580 | - api.contentful.com 581 | response: 582 | status: 583 | code: 200 584 | message: OK 585 | headers: 586 | "^access-Control-Expose-Headers": 587 | - Etag 588 | Accept-Ranges: 589 | - bytes 590 | Access-Control-Allow-Headers: 591 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 592 | Access-Control-Allow-Methods: 593 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 594 | Access-Control-Allow-Origin: 595 | - "*" 596 | Access-Control-Max-Age: 597 | - '1728000' 598 | Cache-Control: 599 | - max-age=0 600 | Content-Type: 601 | - application/vnd.contentful.management.v1+json 602 | Date: 603 | - Fri, 05 Sep 2014 11:39:53 GMT 604 | Etag: 605 | - '"30e7a28ed3dbfc3b90bc324b03fb16a8"' 606 | Server: 607 | - nginx 608 | Status: 609 | - 200 OK 610 | X-Contentful-Request-Id: 611 | - 85f-935734182 612 | Content-Length: 613 | - '2619' 614 | Connection: 615 | - keep-alive 616 | body: 617 | encoding: UTF-8 618 | string: | 619 | { 620 | "sys":{ 621 | "type":"Array" 622 | }, 623 | "items":[ 624 | { 625 | "sys":{ 626 | "type":"Locale", 627 | "id":"3KpVOfIfikrLpwqCa49ami", 628 | "version":0, 629 | "space":{ 630 | "sys":{ 631 | "type":"Link", 632 | "linkType":"Space", 633 | "id":"v2umtz8ths9v" 634 | } 635 | }, 636 | "createdBy":{ 637 | "sys":{ 638 | "type":"Link", 639 | "linkType":"User", 640 | "id":"1E7acJL8I5XUXAMHQt9Grs" 641 | } 642 | }, 643 | "createdAt":"2014-08-21T13:32:12Z", 644 | "updatedBy":{ 645 | "sys":{ 646 | "type":"Link", 647 | "linkType":"User", 648 | "id":"1E7acJL8I5XUXAMHQt9Grs" 649 | } 650 | }, 651 | "updatedAt":"2014-08-21T13:32:12Z" 652 | }, 653 | "name":"U.S. English", 654 | "code":"en-US", 655 | "default":true, 656 | "contentManagementApi":true, 657 | "publish":true, 658 | "contentDeliveryApi":true 659 | }, 660 | { 661 | "sys":{ 662 | "type":"Locale", 663 | "id":"3PFj46pytOXQnNSEzqNsaO", 664 | "version":0, 665 | "space":{ 666 | "sys":{ 667 | "type":"Link", 668 | "linkType":"Space", 669 | "id":"v2umtz8ths9v" 670 | } 671 | }, 672 | "createdBy":{ 673 | "sys":{ 674 | "type":"Link", 675 | "linkType":"User", 676 | "id":"1E7acJL8I5XUXAMHQt9Grs" 677 | } 678 | }, 679 | "createdAt":"2014-08-21T13:32:16Z", 680 | "updatedBy":{ 681 | "sys":{ 682 | "type":"Link", 683 | "linkType":"User", 684 | "id":"1E7acJL8I5XUXAMHQt9Grs" 685 | } 686 | }, 687 | "updatedAt":"2014-08-21T13:32:16Z" 688 | }, 689 | "name":"German", 690 | "code":"de-DE", 691 | "default":false, 692 | "contentManagementApi":true, 693 | "publish":true, 694 | "contentDeliveryApi":true 695 | }, 696 | { 697 | "sys":{ 698 | "type":"Locale", 699 | "id":"3RN3vNgufcurpT9L5o8PBA", 700 | "version":0, 701 | "space":{ 702 | "sys":{ 703 | "type":"Link", 704 | "linkType":"Space", 705 | "id":"v2umtz8ths9v" 706 | } 707 | }, 708 | "createdBy":{ 709 | "sys":{ 710 | "type":"Link", 711 | "linkType":"User", 712 | "id":"1E7acJL8I5XUXAMHQt9Grs" 713 | } 714 | }, 715 | "createdAt":"2014-08-21T13:32:18Z", 716 | "updatedBy":{ 717 | "sys":{ 718 | "type":"Link", 719 | "linkType":"User", 720 | "id":"1E7acJL8I5XUXAMHQt9Grs" 721 | } 722 | }, 723 | "updatedAt":"2014-08-21T13:32:18Z" 724 | }, 725 | "name":"Polish", 726 | "code":"pl-PL", 727 | "default":false, 728 | "contentManagementApi":true, 729 | "publish":true, 730 | "contentDeliveryApi":true 731 | } 732 | ], 733 | "total":3, 734 | "limit":25, 735 | "skip":0} 736 | http_version: 737 | recorded_at: Fri, 05 Sep 2014 11:40:25 GMT 738 | - request: 739 | method: put 740 | uri: https://api.contentful.com/spaces/v2umtz8ths9v/entries/14498XWGiIwQyOAmKq2YeO 741 | body: 742 | encoding: UTF-8 743 | string: '{"fields":{"name":{"en-US":"Sports EN","de-DE":"Sport DE","pl-PL":"Sport 744 | PL"},"description":{"en-US":"Sports category EN"}}}' 745 | headers: 746 | User-Agent: 747 | - RubyContenfulManagementGem/0.1.0 748 | Authorization: 749 | - Bearer 750 | Content-Type: 751 | - application/vnd.contentful.management.v1+json 752 | X-Contentful-Version: 753 | - '2' 754 | Host: 755 | - api.contentful.com 756 | response: 757 | status: 758 | code: 200 759 | message: OK 760 | headers: 761 | "^access-Control-Expose-Headers": 762 | - Etag 763 | Access-Control-Allow-Headers: 764 | - Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization 765 | Access-Control-Allow-Methods: 766 | - DELETE,GET,HEAD,POST,PUT,OPTIONS 767 | Access-Control-Allow-Origin: 768 | - "*" 769 | Access-Control-Max-Age: 770 | - '1728000' 771 | Cf-Space-Id: 772 | - v2umtz8ths9v 773 | Content-Type: 774 | - application/vnd.contentful.management.v1+json 775 | Date: 776 | - Fri, 05 Sep 2014 11:39:54 GMT 777 | Etag: 778 | - '"7a74ee95b8d688605c668fb33eb36396"' 779 | Server: 780 | - nginx 781 | X-Powered-By: 782 | - Express 783 | Content-Length: 784 | - '922' 785 | Connection: 786 | - keep-alive 787 | body: 788 | encoding: UTF-8 789 | string: | 790 | { 791 | "fields": { 792 | "name": { 793 | "en-US": "Sports EN", 794 | "de-DE": "Sport DE", 795 | "pl-PL": "Sport PL" 796 | }, 797 | "description": { 798 | "en-US": "Sports category EN" 799 | } 800 | }, 801 | "sys": { 802 | "id": "14498XWGiIwQyOAmKq2YeO", 803 | "type": "Entry", 804 | "createdAt": "2014-09-04T18:03:24.057Z", 805 | "createdBy": { 806 | "sys": { 807 | "type": "Link", 808 | "linkType": "User", 809 | "id": "1E7acJL8I5XUXAMHQt9Grs" 810 | } 811 | }, 812 | "space": { 813 | "sys": { 814 | "type": "Link", 815 | "linkType": "Space", 816 | "id": "v2umtz8ths9v" 817 | } 818 | }, 819 | "contentType": { 820 | "sys": { 821 | "type": "Link", 822 | "linkType": "ContentType", 823 | "id": "category_content_type" 824 | } 825 | }, 826 | "version": 3, 827 | "updatedAt": "2014-09-05T11:39:54.135Z", 828 | "updatedBy": { 829 | "sys": { 830 | "type": "Link", 831 | "linkType": "User", 832 | "id": "1E7acJL8I5XUXAMHQt9Grs" 833 | } 834 | } 835 | } 836 | } 837 | http_version: 838 | recorded_at: Fri, 05 Sep 2014 11:40:26 GMT 839 | recorded_with: VCR 2.9.2 840 | --------------------------------------------------------------------------------