xing-backend 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/deprecated_classes.rb +28 -0
- data/lib/xing/controllers/base.rb +40 -0
- data/lib/xing/controllers/root_resources_controller.rb +12 -0
- data/lib/xing/engine.rb +27 -0
- data/lib/xing/mappers/base.rb +135 -0
- data/lib/xing/mappers.rb +6 -0
- data/lib/xing/serializers/base.rb +50 -0
- data/lib/xing/serializers/root_resources.rb +9 -0
- data/lib/xing/serializers.rb +7 -0
- data/lib/xing/services/error_converter.rb +47 -0
- data/lib/xing/services/json_tree_lister.rb +56 -0
- data/lib/xing/services/snapshot_fetcher.rb +33 -0
- data/lib/xing/services/snapshot_writer.rb +19 -0
- data/lib/xing/services.rb +9 -0
- data/lib/xing-backend.rb +34 -0
- data/spec/deprecated_classes/active_model_error_converter_spec.rb +11 -0
- data/spec/deprecated_classes/base_serializer_spec.rb +11 -0
- data/spec/deprecated_classes/hypermedia_json_mapper_spec.rb +11 -0
- data/spec/deprecated_classes/json_tree_lister_spec.rb +14 -0
- data/spec/deprecated_classes/remote_snapshot_fetcher_spec.rb +8 -0
- data/spec/deprecated_classes/resources_serializer_spec.rb +12 -0
- data/spec/xing/controllers/base_spec.rb +7 -0
- data/spec/xing/controllers/root_resources_controller_spec.rb +8 -0
- data/spec/xing/mappers/base_spec.rb +56 -0
- data/spec/xing/serializers/base_spec.rb +32 -0
- data/spec/xing/serializers/root_resources_spec.rb +20 -0
- data/spec/xing/services/error_converter_spec.rb +61 -0
- data/spec/xing/services/json_tree_lister_spec.rb +109 -0
- data/spec/xing/services/snapshot_fetcher_spec.rb +75 -0
- data/spec/xing_spec.rb +7 -0
- data/spec_help/dummy/README.rdoc +28 -0
- data/spec_help/dummy/Rakefile +6 -0
- data/spec_help/dummy/app/assets/javascripts/application.js +13 -0
- data/spec_help/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec_help/dummy/app/controllers/application_controller.rb +5 -0
- data/spec_help/dummy/app/helpers/application_helper.rb +2 -0
- data/spec_help/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec_help/dummy/bin/bundle +3 -0
- data/spec_help/dummy/bin/rails +4 -0
- data/spec_help/dummy/bin/rake +4 -0
- data/spec_help/dummy/bin/setup +29 -0
- data/spec_help/dummy/config/application.rb +25 -0
- data/spec_help/dummy/config/boot.rb +5 -0
- data/spec_help/dummy/config/database.yml +25 -0
- data/spec_help/dummy/config/environment.rb +5 -0
- data/spec_help/dummy/config/environments/development.rb +41 -0
- data/spec_help/dummy/config/environments/production.rb +79 -0
- data/spec_help/dummy/config/environments/test.rb +42 -0
- data/spec_help/dummy/config/initializers/assets.rb +11 -0
- data/spec_help/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec_help/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec_help/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec_help/dummy/config/initializers/inflections.rb +16 -0
- data/spec_help/dummy/config/initializers/mime_types.rb +4 -0
- data/spec_help/dummy/config/initializers/session_store.rb +3 -0
- data/spec_help/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec_help/dummy/config/locales/en.yml +23 -0
- data/spec_help/dummy/config/routes.rb +56 -0
- data/spec_help/dummy/config/secrets.yml +22 -0
- data/spec_help/dummy/config.ru +4 -0
- data/spec_help/dummy/db/test.sqlite3 +0 -0
- data/spec_help/dummy/log/test.log +48 -0
- data/spec_help/dummy/public/404.html +67 -0
- data/spec_help/dummy/public/422.html +67 -0
- data/spec_help/dummy/public/500.html +66 -0
- data/spec_help/dummy/public/favicon.ico +0 -0
- data/spec_help/spec_helper.rb +29 -0
- metadata +222 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 81e5fbc0eab9a8177181d26d407b447a7bde5e78
|
4
|
+
data.tar.gz: 5e55cf12697cab2d64f021c4e918643382867212
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ae67633934b7e3b807aca8f178895a52d1751188b04c4cebfd051abf5076280eb9c9063ab612cc8c12137bf70c02ebb64bd4999339c1451d953f9a932c0a6316
|
7
|
+
data.tar.gz: 0ea48e465a1e35135b46c093161ddd836c8117b3568a2765cb223044f9a53a3dfb745d4d12306fc6b9a320c7c6c5ae4def2ca7d32d68b8c4bef478b03a5219a6
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'xing-backend'
|
2
|
+
require 'active_support/deprecation'
|
3
|
+
|
4
|
+
module Xing
|
5
|
+
DEPRECATED_CLASSES = {
|
6
|
+
:HypermediaJSONMapper => Xing::Mappers::Base,
|
7
|
+
:BaseSerializer => Xing::Serializers::Base,
|
8
|
+
:ResourcesSerializer => Xing::Serializers::RootResources,
|
9
|
+
:JsonTreeLister => Xing::Services::JsonTreeLister,
|
10
|
+
:ActiveModelErrorConverter => Xing::Services::ErrorConverter,
|
11
|
+
:RemoteSnapshotFetcher => Xing::Services::SnapshotFetcher
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
#Xing::DEPRECATED_CLASSES.each do |old, new|
|
16
|
+
|
17
|
+
## with great power comes great responsibility
|
18
|
+
#Object.const_set(old, ActiveSupport::Deprecation::DeprecatedConstantProxy.new(old, new))
|
19
|
+
#end
|
20
|
+
|
21
|
+
def Object.const_missing(name)
|
22
|
+
if (klass = ::Xing::DEPRECATED_CLASSES[name.to_sym])
|
23
|
+
warn "[DEPRECATION] #{name} is deprecated. Please use #{klass.to_s} instead."
|
24
|
+
klass
|
25
|
+
else
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'devise_token_auth'
|
2
|
+
|
3
|
+
module Xing
|
4
|
+
module Controllers
|
5
|
+
class Base < ActionController::Base
|
6
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
7
|
+
|
8
|
+
respond_to :json
|
9
|
+
|
10
|
+
protect_from_forgery
|
11
|
+
before_filter :check_format
|
12
|
+
|
13
|
+
def check_format
|
14
|
+
if request.subdomains.include? Xing.backend_subdomain
|
15
|
+
if request.headers["Accept"] =~ /json/
|
16
|
+
params[:format] = :json
|
17
|
+
else
|
18
|
+
render :nothing => true, :status => 406
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def json_body
|
24
|
+
@json_body ||= request.body.read
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse_json
|
28
|
+
@parsed_json ||= JSON.parse(json_body)
|
29
|
+
end
|
30
|
+
|
31
|
+
def failed_to_process(error_document)
|
32
|
+
render :status => 422, :json => error_document
|
33
|
+
end
|
34
|
+
|
35
|
+
def successful_create(new_resource_path)
|
36
|
+
render :status => 201, :json => {}, :location => new_resource_path
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rails/rfc6570'
|
2
|
+
|
3
|
+
module Xing
|
4
|
+
module Controllers
|
5
|
+
class RootResourcesController < ::Xing::Controllers::Base
|
6
|
+
def index
|
7
|
+
@resources = rfc6570_routes(ignore: %w(format), path_only: true)
|
8
|
+
render :json => Xing::Serializers::RootResources.new(@resources)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/xing/engine.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Xing
|
2
|
+
|
3
|
+
class Engine < ::Rails::Engine
|
4
|
+
isolate_namespace Xing
|
5
|
+
|
6
|
+
config.autoload_paths += Dir[File.join(__FILE__, '../controllers/**/')]
|
7
|
+
|
8
|
+
config.generators do |g|
|
9
|
+
g.test_framework :rspec
|
10
|
+
end
|
11
|
+
|
12
|
+
# The ErrorConverter leverages (abuses?) the I18n mechanism to translate
|
13
|
+
# ActiveModel validation errors into Xing JSON resource errors. Here we
|
14
|
+
# need to make sure the locales file for language 'json' is loaded for
|
15
|
+
# I18n.
|
16
|
+
initializer 'xing errors locales path' do
|
17
|
+
I18n.load_path += Dir[File.join(File.dirname(__FILE__), '..', 'config', 'locales', '*.{rb,yml}')]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set the backend subdomain if it hasn't been configured by the user.
|
21
|
+
initializer 'set subdomain' do
|
22
|
+
Xing.configure do |xng_config|
|
23
|
+
xng_config.backend_subdomain ||= 'api'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# This code is only used in the context of Rails apps, and depends pretty
|
2
|
+
# heavily on rails core extensions, so we are requiring them here.
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
|
6
|
+
module Xing
|
7
|
+
module Mappers
|
8
|
+
class Base
|
9
|
+
class MissingLinkException < Exception; end
|
10
|
+
|
11
|
+
# Subclasses must define:
|
12
|
+
# aliases -- for self.record
|
13
|
+
# record_class -- if the mapper maps to an AR object
|
14
|
+
#
|
15
|
+
# Subclasses should usually define:
|
16
|
+
# assign_values -- move values from JSON into the mapped AR record
|
17
|
+
#
|
18
|
+
# Subclasses may also want to define:
|
19
|
+
# find_existing_record -- for locating the underlying AR record
|
20
|
+
# build_new_record -- for for instantiating a new underlying AR record
|
21
|
+
# map_nested_models
|
22
|
+
# build_errors -- if simply copying AR errors is insufficient
|
23
|
+
# save -- if they need to save more than 1 AR record
|
24
|
+
|
25
|
+
# When updating records, pass the locator (e.g. DB id, url_slug, or other
|
26
|
+
# unique resource extracted from the resource path) as the second argument.
|
27
|
+
def initialize(json, locator = nil)
|
28
|
+
@source_json = json
|
29
|
+
if @source_json.is_a? String
|
30
|
+
@source_hash = JSON.parse(json).with_indifferent_access
|
31
|
+
else
|
32
|
+
@source_hash = @source_json
|
33
|
+
end
|
34
|
+
@locator = locator
|
35
|
+
end
|
36
|
+
attr_accessor :locator, :error_data
|
37
|
+
attr_writer :record
|
38
|
+
|
39
|
+
def router
|
40
|
+
Rails.application.routes
|
41
|
+
end
|
42
|
+
|
43
|
+
def normalize_path(path)
|
44
|
+
path = "/#{path}"
|
45
|
+
path.squeeze!('/')
|
46
|
+
path.sub!(%r{/+\Z}, '')
|
47
|
+
path.gsub!(/(%[a-f0-9]{2})/) { $1.upcase }
|
48
|
+
path = '/' if path == ''
|
49
|
+
path
|
50
|
+
end
|
51
|
+
|
52
|
+
# This helper is used to deconstruct a URL for the purpose of extracting
|
53
|
+
# components. For example, menu_item_mapper uses it to extract the url_slug
|
54
|
+
# component of a page route. We are here abusing recognize_path, which isn't
|
55
|
+
# supposed to be used outside of tests (see
|
56
|
+
# https://github.com/rails/rails/issues/2656), but we don't know what the
|
57
|
+
# alternative is.
|
58
|
+
def route_to(path)
|
59
|
+
path = "http://#{BACKEND_SUBDOMAIN}.example.com#{normalize_path(path)}";
|
60
|
+
router.recognize_path(path)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Default save - subclasses might override
|
64
|
+
def save
|
65
|
+
perform_mapping
|
66
|
+
unless self.errors[:data].present?
|
67
|
+
self.record.save
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Default for finding an existing record - override this *or* define
|
72
|
+
# #record_class (e.g. `return Page`
|
73
|
+
def find_existing_record
|
74
|
+
@record = record_class.find(@locator)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Default for building a new record - override this *or* define #record_class
|
78
|
+
# (e.g. `return Page`
|
79
|
+
def build_new_record
|
80
|
+
@record = record_class.new
|
81
|
+
end
|
82
|
+
|
83
|
+
def perform_mapping
|
84
|
+
data = unwrap_data(@source_hash)
|
85
|
+
self.error_data = Hash.new { |hash, key| hash[key] = {} }
|
86
|
+
|
87
|
+
assign_values(data)
|
88
|
+
map_nested_models
|
89
|
+
build_errors
|
90
|
+
end
|
91
|
+
|
92
|
+
def unwrap_data(hash)
|
93
|
+
hash['data'].with_indifferent_access
|
94
|
+
end
|
95
|
+
|
96
|
+
def wrap_data(hash)
|
97
|
+
{
|
98
|
+
data: hash
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
def record
|
103
|
+
@record ||= if !locator.nil?
|
104
|
+
find_existing_record
|
105
|
+
else
|
106
|
+
build_new_record
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def assign_values(data_hash)
|
111
|
+
# Override in subclasses to assign needed values here
|
112
|
+
record # force loading or creation of the underlying DB record
|
113
|
+
update_record
|
114
|
+
end
|
115
|
+
|
116
|
+
# Do nothing if there are no nested models
|
117
|
+
# Override this method in subclass if necessary
|
118
|
+
def map_nested_models
|
119
|
+
end
|
120
|
+
|
121
|
+
def build_errors
|
122
|
+
self.add_ar_arrors(self.record)
|
123
|
+
end
|
124
|
+
|
125
|
+
def errors
|
126
|
+
wrap_data(error_data)
|
127
|
+
end
|
128
|
+
|
129
|
+
def add_ar_arrors(object)
|
130
|
+
object_errors = ActiveModelErrorConverter.new(object).convert
|
131
|
+
error_data.deep_merge!(object_errors)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
data/lib/xing/mappers.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'active_model_serializers'
|
3
|
+
|
4
|
+
module Xing
|
5
|
+
module Serializers
|
6
|
+
|
7
|
+
# The base class for all Xing serializers that produce
|
8
|
+
# Xing Hypermedia JSON resources. In general, subclasses
|
9
|
+
# of Xing::Serializers::Base should:
|
10
|
+
#
|
11
|
+
# * Define a links method that returns a hash of hypermedia links to
|
12
|
+
# related resources
|
13
|
+
#
|
14
|
+
# * Specify the attributes (via the ActiveModel::Serializers 'attributes'
|
15
|
+
# class method) that will be copied into the data: block
|
16
|
+
# of the generated resource.
|
17
|
+
#
|
18
|
+
# * Define methods for any attributes that do not exist as plain attributes
|
19
|
+
# in the ActiveModel being serialized. Note that this may (and often will) include
|
20
|
+
# calling other serializers on related resources or other data, in order to
|
21
|
+
# generate embedded resources.
|
22
|
+
#
|
23
|
+
# Xing serializers descend from ActiveModel::Serializer and are typically
|
24
|
+
# instantiated with an instance of an ActiveModel model in the usual way.
|
25
|
+
#
|
26
|
+
class Base < ActiveModel::Serializer
|
27
|
+
|
28
|
+
def routes
|
29
|
+
Rails.application.routes.url_helpers
|
30
|
+
end
|
31
|
+
|
32
|
+
def root
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
def as_json_with_wrap(options={})
|
37
|
+
{
|
38
|
+
:links => links,
|
39
|
+
:data => as_json_without_wrap
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def links
|
44
|
+
{}
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method_chain :as_json, :wrap
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Xing
|
2
|
+
module Services
|
3
|
+
class ErrorConverter
|
4
|
+
|
5
|
+
|
6
|
+
def initialize(am_object)
|
7
|
+
@am_object = am_object
|
8
|
+
end
|
9
|
+
attr_reader :am_object
|
10
|
+
|
11
|
+
# This is a terrible hack to preserve the semantic meaning of
|
12
|
+
# different error types -- neccesary because ActiveModel::Errors
|
13
|
+
# frustratingly translates semantic error messages through i18n
|
14
|
+
# as soon as it gets them
|
15
|
+
def json_errors
|
16
|
+
@json_errors ||= begin
|
17
|
+
old_locale = I18n.locale
|
18
|
+
I18n.locale = "json"
|
19
|
+
am_object.valid?
|
20
|
+
error_hash = am_object.errors.to_hash.deep_dup
|
21
|
+
I18n.locale = old_locale
|
22
|
+
error_hash
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def regular_errors
|
27
|
+
@regular_errors ||= begin
|
28
|
+
am_object.valid?
|
29
|
+
am_object.errors.to_hash.deep_dup
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def convert
|
34
|
+
final_errors = {}
|
35
|
+
json_errors.each_key do |key|
|
36
|
+
final_errors[key] = {
|
37
|
+
:type => json_errors[key][0],
|
38
|
+
:message => regular_errors[key][0]
|
39
|
+
}
|
40
|
+
end
|
41
|
+
final_errors
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'active_model_serializers'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
module Xing
|
5
|
+
module Services
|
6
|
+
class JsonTreeLister
|
7
|
+
|
8
|
+
class TreeNode
|
9
|
+
include ActiveModel::SerializerSupport
|
10
|
+
|
11
|
+
def initialize(node, children)
|
12
|
+
@node = node
|
13
|
+
@children = children
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :node, :children
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(nodes, node_serializer)
|
20
|
+
@nodes = nodes
|
21
|
+
@node_serializer = node_serializer
|
22
|
+
@stack = [[]]
|
23
|
+
@path = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_node(node, children)
|
27
|
+
@node_serializer.new(TreeNode.new(node, children)).as_json
|
28
|
+
end
|
29
|
+
|
30
|
+
def pop_level
|
31
|
+
children = @stack.pop
|
32
|
+
@stack.last << render_node(@path.pop, children)
|
33
|
+
end
|
34
|
+
|
35
|
+
def render
|
36
|
+
(@nodes + [nil]).each_cons(2) do |this, after|
|
37
|
+
until @path.empty? or @path.last.is_ancestor_of?(this)
|
38
|
+
pop_level
|
39
|
+
end
|
40
|
+
if after.nil? or !this.is_ancestor_of?(after)
|
41
|
+
@stack.last << render_node(this, [])
|
42
|
+
else
|
43
|
+
@path << this
|
44
|
+
@stack << []
|
45
|
+
end
|
46
|
+
end
|
47
|
+
until @path.empty?
|
48
|
+
pop_level
|
49
|
+
end
|
50
|
+
return @stack.last.first
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'addressable/uri'
|
3
|
+
require 'xing/services/snapshot_writer'
|
4
|
+
require 'sidekiq/worker'
|
5
|
+
|
6
|
+
module Xing::Services
|
7
|
+
class SnapshotFetcher
|
8
|
+
include Sidekiq::Worker
|
9
|
+
include SnapshotWriter
|
10
|
+
|
11
|
+
def perform(url, path)
|
12
|
+
admin_server = Rails.application.secrets.snapshot_server['url']
|
13
|
+
user_password = "#{Rails.application.secrets.snapshot_server['user']}:#{Rails.application.secrets.snapshot_server['password']}"
|
14
|
+
snapshot_url = Addressable::URI.join(url,path).to_s
|
15
|
+
request = Typhoeus::Request.new(admin_server, userpwd: user_password, params: { url: snapshot_url })
|
16
|
+
|
17
|
+
hydra = Typhoeus::Hydra.new
|
18
|
+
hydra.queue(request)
|
19
|
+
hydra.run
|
20
|
+
|
21
|
+
response = request.response
|
22
|
+
|
23
|
+
if response.success?
|
24
|
+
html = response.body
|
25
|
+
write(path, html)
|
26
|
+
else
|
27
|
+
logger.warn response.status_message
|
28
|
+
logger.warn response.body
|
29
|
+
raise "Query to #{admin_server} for #{path} failed!"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Xing::Services
|
2
|
+
module SnapshotWriter
|
3
|
+
def write(path, html)
|
4
|
+
if Rails.env.test?
|
5
|
+
snapshot_file = "#{ Rails.root }/spec/fixtures/sitemap_scratch/#{path.present? ? path : 'index'}.html"
|
6
|
+
else
|
7
|
+
snapshot_file = "#{ Rails.root }/public/frontend_snapshots/#{path.present? ? path : 'index'}.html"
|
8
|
+
end
|
9
|
+
dirname = File.dirname(snapshot_file)
|
10
|
+
unless File.directory?(dirname)
|
11
|
+
FileUtils.mkdir_p(dirname)
|
12
|
+
end
|
13
|
+
|
14
|
+
File.open(snapshot_file, "w+:ASCII-8BIT:UTF-8") do |f|
|
15
|
+
f.write(html)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/xing-backend.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'xing_backend_token_auth'
|
3
|
+
require 'rails/rfc6570'
|
4
|
+
require 'sidekiq'
|
5
|
+
|
6
|
+
module Xing
|
7
|
+
mattr_accessor :backend_subdomain
|
8
|
+
|
9
|
+
# Configure xing via pattern similar to Rails:
|
10
|
+
#
|
11
|
+
# Xing.configure do |config|
|
12
|
+
# config.setting = 'value'
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Supported settings right now are:
|
16
|
+
# * backend_subdomain (default: 'api')
|
17
|
+
def self.configure(&block)
|
18
|
+
yield self
|
19
|
+
end
|
20
|
+
|
21
|
+
module Controllers
|
22
|
+
autoload :Base, 'xing/controllers/base'
|
23
|
+
|
24
|
+
# NOTE: The rails router expects the the controller to have "Controller" as
|
25
|
+
# the suffix of the name, or it complains.
|
26
|
+
autoload :RootResourcesController, 'xing/controllers/root_resources_controller'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'xing/mappers'
|
31
|
+
require 'xing/engine'
|
32
|
+
require 'xing/serializers'
|
33
|
+
require 'xing/services'
|
34
|
+
require 'deprecated_classes'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'deprecated_classes'
|
2
|
+
|
3
|
+
describe ActiveModelErrorConverter, :type => :deprecation do
|
4
|
+
let :resource do
|
5
|
+
double('resource')
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be the correct class" do
|
9
|
+
expect(ActiveModelErrorConverter.new(resource)).to be_a(Xing::Services::ErrorConverter)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'deprecated_classes'
|
2
|
+
|
3
|
+
describe JsonTreeLister, :type => :deprecation do
|
4
|
+
let :models do
|
5
|
+
double('models')
|
6
|
+
end
|
7
|
+
let :serializer do
|
8
|
+
double('serializer')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be the correct class" do
|
12
|
+
expect(JsonTreeLister.new(models, serializer)).to be_a(Xing::Services::JsonTreeLister)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
require 'deprecated_classes'
|
3
|
+
|
4
|
+
describe ResourcesSerializer do
|
5
|
+
let :resource do
|
6
|
+
double('hash_of_links')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be the correct class" do
|
10
|
+
expect(ResourcesSerializer.new(resource)).to be_a(Xing::Serializers::RootResources)
|
11
|
+
end
|
12
|
+
end
|