backframe 0.0.49 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +16 -0
  3. data/.gitignore +2 -2
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +1156 -0
  6. data/Gemfile +9 -13
  7. data/README.md +133 -4
  8. data/Rakefile +3 -7
  9. data/backframe.gemspec +10 -11
  10. data/circle.yml +5 -2
  11. data/lib/backframe.rb +21 -34
  12. data/lib/backframe/mime.rb +4 -0
  13. data/lib/backframe/query.rb +48 -0
  14. data/lib/backframe/query/sort.rb +29 -0
  15. data/lib/backframe/railtie.rb +1 -16
  16. data/lib/backframe/response.rb +60 -0
  17. data/lib/backframe/response/adapter/csv.rb +39 -0
  18. data/lib/backframe/response/adapter/json.rb +53 -0
  19. data/lib/backframe/response/adapter/xlsx.rb +41 -0
  20. data/lib/backframe/response/adapter/xml.rb +37 -0
  21. data/lib/backframe/response/collection.rb +43 -0
  22. data/lib/backframe/response/fields.rb +62 -0
  23. data/lib/backframe/response/record.rb +38 -0
  24. data/lib/backframe/service.rb +60 -0
  25. data/lib/backframe/service/result/base.rb +24 -0
  26. data/lib/backframe/service/result/failure.rb +21 -0
  27. data/lib/backframe/service/result/success.rb +21 -0
  28. data/lib/backframe/version.rb +1 -1
  29. data/spec/fixtures/active_record.rb +22 -0
  30. data/spec/fixtures/models.rb +25 -0
  31. data/spec/fixtures/queries.rb +28 -0
  32. data/spec/fixtures/seeds.rb +12 -0
  33. data/spec/fixtures/serializers.rb +23 -0
  34. data/spec/fixtures/services.rb +26 -0
  35. data/spec/query/sort_spec.rb +47 -0
  36. data/spec/query_spec.rb +63 -0
  37. data/spec/response/adapter/csv_spec.rb +47 -0
  38. data/spec/response/adapter/json_spec.rb +66 -0
  39. data/spec/response/adapter/xlsx_spec.rb +59 -0
  40. data/spec/response/adapter/xml_spec.rb +63 -0
  41. data/spec/response/fields_spec.rb +45 -0
  42. data/spec/response/record_spec.rb +45 -0
  43. data/spec/response_spec.rb +153 -0
  44. data/spec/service/result/failure_spec.rb +16 -0
  45. data/spec/service/result/sucess_spec.rb +17 -0
  46. data/spec/service_spec.rb +16 -0
  47. data/spec/spec_helper.rb +15 -52
  48. metadata +78 -81
  49. data/lib/backframe/actioncontroller/acts_as_activation.rb +0 -70
  50. data/lib/backframe/actioncontroller/acts_as_api.rb +0 -39
  51. data/lib/backframe/actioncontroller/acts_as_api/adapter.rb +0 -53
  52. data/lib/backframe/actioncontroller/acts_as_api/errors.rb +0 -48
  53. data/lib/backframe/actioncontroller/acts_as_api/headers.rb +0 -11
  54. data/lib/backframe/actioncontroller/acts_as_api/page.rb +0 -181
  55. data/lib/backframe/actioncontroller/acts_as_reset.rb +0 -86
  56. data/lib/backframe/actioncontroller/acts_as_resource.rb +0 -92
  57. data/lib/backframe/actioncontroller/acts_as_resource/actions.rb +0 -100
  58. data/lib/backframe/actioncontroller/acts_as_session.rb +0 -80
  59. data/lib/backframe/activerecord/acts_as_activable.rb +0 -50
  60. data/lib/backframe/activerecord/acts_as_distinct.rb +0 -49
  61. data/lib/backframe/activerecord/acts_as_enum.rb +0 -62
  62. data/lib/backframe/activerecord/acts_as_orderable.rb +0 -40
  63. data/lib/backframe/activerecord/acts_as_percent.rb +0 -46
  64. data/lib/backframe/activerecord/acts_as_phone.rb +0 -59
  65. data/lib/backframe/activerecord/acts_as_user.rb +0 -101
  66. data/lib/backframe/activerecord/default_values.rb +0 -32
  67. data/lib/backframe/activerecord/filter_sort.rb +0 -79
  68. data/lib/backframe/activerecord/migration.rb +0 -25
  69. data/lib/backframe/image_cache/image_cache.rb +0 -45
  70. data/lib/backframe/image_cache/lib/asset.rb +0 -109
  71. data/lib/backframe/image_cache/lib/cache.rb +0 -67
  72. data/lib/backframe/image_cache/lib/conversions.rb +0 -132
  73. data/lib/backframe/models/activation.rb +0 -60
  74. data/lib/backframe/models/activity.rb +0 -40
  75. data/lib/backframe/models/reset.rb +0 -59
  76. data/lib/backframe/models/story.rb +0 -9
  77. data/lib/backframe/serializers/activity_serializer.rb +0 -44
  78. data/spec/backframe/acts_as_api_spec.rb +0 -225
  79. data/spec/backframe/acts_as_resource_spec.rb +0 -178
  80. data/spec/support/example_factory.rb +0 -9
  81. data/spec/support/example_serializer.rb +0 -3
  82. data/spec/support/schema.rb +0 -8
@@ -1,67 +0,0 @@
1
- require 'stringio'
2
-
3
- module Backframe
4
-
5
- module ImageCache
6
-
7
- class Cache
8
-
9
- def initialize(filepath, conversions)
10
- @filepath = filepath
11
- @conversions = conversions
12
- end
13
-
14
- def process
15
- begin
16
- test(filepath, conversions)
17
- rescue
18
- test(nil, conversions)
19
- end
20
- end
21
-
22
- def test(filepath, conversions)
23
- filekey = filepath || 'default.jpg'
24
- normalized = Backframe::ImageCache::Conversions.new(conversions)
25
- key = "imagecache/#{normalized.to_s}/#{filekey}"
26
- if !redis.get(key)
27
- asset = Backframe::ImageCache::Asset.new(filepath, normalized).process
28
- upload_to_s3(asset, key)
29
- save_to_redis(key)
30
- end
31
- return OpenStruct.new(:success => true, :url => "#{Rails.application.config.cdn_url}/#{key}")
32
- end
33
-
34
- private
35
-
36
- attr_reader :filepath, :conversions
37
-
38
- def save_to_redis(key)
39
- redis.set(key, true)
40
- redis.expire(key, (7 * 24 * 60 * 60))
41
- end
42
-
43
- def upload_to_s3(asset, key)
44
- headers = { :acl => 'public-read', :content_type => asset.content_type, :cache_control => 'max-age=315360000, no-transform, public', :content_encoding => 'gzip' }
45
- bucket = s3.buckets[aws['bucket']]
46
- bucket.objects.create(key, asset.data, headers)
47
- end
48
-
49
- def aws
50
- @aws ||= YAML.load_file("#{Rails.root}/config/aws.yml")[Rails.env]
51
- end
52
-
53
- def s3
54
- @s3 ||= AWS::S3.new(:access_key_id => aws['access_key_id'], :secret_access_key => aws['secret_access_key'])
55
- end
56
-
57
- def redis
58
- return @redis if @redis.present?
59
- config = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]
60
- @redis = Redis.new(:host => config['host'], :port => config['port'], :db => config[:cache])
61
- end
62
-
63
- end
64
-
65
- end
66
-
67
- end
@@ -1,132 +0,0 @@
1
- require 'stringio'
2
-
3
- module Backframe
4
-
5
- module ImageCache
6
-
7
- class Conversions
8
-
9
- def initialize(conversions)
10
- @conversions = normalize_conversions(conversions)
11
- end
12
-
13
- def to_s
14
- output = []
15
- conversions.each do |conversion|
16
- if conversion.key?(:fit)
17
- output << "F#{conversion[:fit][:width]}X#{conversion[:fit][:height]}D#{conversion[:density]}"
18
- elsif conversion.key?(:width)
19
- output << "W#{conversion[:width]}D#{conversion[:density]}"
20
- elsif conversion.key?(:height)
21
- output << "H#{conversion[:height]}D#{conversion[:density]}"
22
- elsif conversion.key?(:crop)
23
- output << "C#{conversion[:crop][:width]}X#{conversion[:crop][:height]}X#{conversion[:crop][:x]}X#{conversion[:crop][:y]}D#{conversion[:density]}"
24
- end
25
- end
26
- output.join("-")
27
- end
28
-
29
- def to_a
30
- conversions
31
- end
32
-
33
- private
34
-
35
- attr_reader :conversions
36
-
37
- #################### CONVERSION HANDLING ####################
38
-
39
- def normalize_conversions(conversions)
40
- if conversions.is_a?(String)
41
- return normalize_conversion_string(conversions)
42
- elsif conversions.is_a?(Symbol)
43
- return normalize_conversion_string(conversions.to_s)
44
- elsif conversions.is_a?(Hash)
45
- return normalize_conversion_array([conversions])
46
- elsif conversions.is_a?(Array)
47
- return normalize_conversion_array(conversions)
48
- elsif conversions.is_a?(Backframe::ImageCache::Conversions)
49
- return conversions.to_a
50
- end
51
- end
52
-
53
- def normalize_conversion_string(string)
54
- output = []
55
- string.upcase.split("-").each do |part|
56
- if part == 'PREVIEW'
57
- output << { :width => 250, :density => 2 }
58
- elsif part == 'TINY'
59
- output << { :fit => { :width => 20, :height => 20 }, :density => 2 }
60
- elsif part == 'SMALL'
61
- output << { :fit => { :width => 40, :height => 40 }, :density => 2 }
62
- elsif part == 'MEDIUM'
63
- output << { :fit => { :width => 250, :height => 250 }, :density => 2 }
64
- elsif matches = part.match(/^F(\d*)X(\d*)(D(\d*))?$/)
65
- density = (matches[3]) ? matches[4] : 1
66
- output << { :fit => { :width => matches[1].to_i, :height => matches[2].to_i }, :density => density.to_i }
67
- elsif matches = part.match(/^W(\d*)(D(\d*))?$/)
68
- density = (matches[2]) ? matches[3] : 1
69
- output << { :width => matches[1].to_i, :density => density.to_i }
70
- elsif matches = part.match(/^H(\d*)(D(\d*))?$/)
71
- density = (matches[2]) ? matches[3] : 1
72
- output << { :height => matches[1].to_i, :density => density.to_i }
73
- elsif matches = part.match(/^C(\d*)X(\d*)X(\d*)X(\d*)(D(\d*))?$/)
74
- density = (matches[4]) ? matches[5] : 1
75
- output << { :crop => { :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i, :density => density.to_i } }
76
- end
77
- end
78
- output
79
- end
80
-
81
- def normalize_conversion_array(array)
82
- output = []
83
- array.each do |conversion|
84
- density = conversion[:density].to_i || 1
85
- if conversion.key?(:preview)
86
- output << { :width => 250, :density => density }
87
- elsif conversion.key?(:tiny)
88
- output << { :fit => { :width => 20, :height => 20 }, :density => density }
89
- elsif conversion.key?(:small)
90
- output << { :fit => { :width => 40, :height => 40 }, :density => density }
91
- elsif conversion.key?(:medium)
92
- output << { :fit => { :width => 250, :height => 250 }, :density => density }
93
- elsif conversion.key?(:fit)
94
- fit = (conversion[:fit].is_a?(String)) ? parse_geometry_string(conversion[:fit]) : parse_geometry_array(conversion[:fit])
95
- output << { :fit => fit, :density => density }
96
- elsif conversion.key?(:width)
97
- output << { :width => conversion[:width].to_i, :density => density }
98
- elsif conversion.key?(:height)
99
- output << { :height => conversion[:height].to_i, :density => density }
100
- elsif conversion.key?(:crop)
101
- crop = (conversion[:crop].is_a?(String)) ? parse_geometry(conversion[:crop]) : parse_geometry_array(conversion[:crop])
102
- output << { :crop => crop, :density => density }
103
- end
104
- end
105
- output
106
- end
107
-
108
- def parse_geometry_string(string)
109
- string = string.upcase
110
- if matches = string.match(/^(\d*)X(\d*)$/)
111
- { :width => matches[1].to_i, :height => matches[2].to_i }
112
- elsif matches = string.match(/^(\d*)X(\d*)X(\d*)X(\d*)$/)
113
- { :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i }
114
- elsif matches = string.match(/^(\d*)X(\d*)\+(\d*)\+(\d*)$/)
115
- { :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i }
116
- end
117
- end
118
-
119
- def parse_geometry_array(array)
120
- output = {}
121
- output[:width] = array[:width].to_i if array.key?(:width)
122
- output[:height] = array[:height].to_i if array.key?(:height)
123
- output[:x] = array[:x].to_i if array.key?(:x)
124
- output[:y] = array[:y].to_i if array.key?(:y)
125
- output
126
- end
127
-
128
- end
129
-
130
- end
131
-
132
- end
@@ -1,60 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- class Activation < ActiveRecord::Base
5
-
6
- liquid_methods :code, :url
7
-
8
- belongs_to :user, :polymorphic => true
9
-
10
- validates_presence_of :user, :token
11
-
12
- after_initialize :init, :if => Proc.new { |o| o.new_record? }
13
- after_create :enforce_uniqueness
14
- after_commit :send_email
15
-
16
- def claim
17
- self.claimed_at = Time.zone.now
18
- self.is_active = false
19
- self.save
20
- self.user.update_attributes(:is_active => true, :activated_at => Time.zone.now)
21
- end
22
-
23
- def expired?
24
- !self.is_active
25
- end
26
-
27
- def url
28
- return "#{Rails.application.config.root_url}/admin/activation/#{self.token}" if self.user_type == 'Admin'
29
- return "#{Rails.application.config.root_url}/account/activation/#{self.token}" if self.user_type == 'Customer'
30
- end
31
-
32
- private
33
-
34
- def init
35
- self.token ||= SecureRandom.hex(32).to_s.upcase[0,32]
36
- self.is_active = true
37
- end
38
-
39
- def set_active
40
- self.is_active = true
41
- end
42
-
43
- def enforce_uniqueness
44
- self.user.activations.where('id != ?', self.id).update_all(:is_active => false)
45
- end
46
-
47
- def send_email
48
- return if Rails.env.test?
49
- if self.user_type == 'Admin'
50
- ApplicationMailer.activation(self).deliver_now!
51
- elsif self.user_type == 'Customer'
52
- template = EmailTemplate.find_by(:code => 'account_activation')
53
- email = EmailDelivery.new(:customer => self.user, :subject => template.subject, :body => template.body)
54
- email.personalize(:customer => self.user, :activation => self)
55
- email.save
56
- end
57
- end
58
-
59
- end
60
- end
@@ -1,40 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- class Activity < ActiveRecord::Base
5
-
6
- belongs_to :subject, :polymorphic => true
7
- belongs_to :object1, :polymorphic => true
8
- belongs_to :object2, :polymorphic => true
9
- belongs_to :story
10
-
11
- validates_presence_of :story, :subject
12
-
13
- default_scope -> { includes(:subject,:object1,:object2,:story).order(:created_at => :desc) }
14
-
15
- def text=(text)
16
- self.story = Backframe::Story.find_or_initialize_by(:text => text)
17
- end
18
-
19
- def subject=(object)
20
- self.subject_type = object.class.name
21
- self.subject_text = object.activity_text
22
- self.subject_id = object.id
23
- end
24
-
25
- def object1=(object)
26
- self.object1_type = object.class.name
27
- self.object1_text = object.activity_text
28
- self.object1_id = object.id
29
- object
30
- end
31
-
32
- def object2=(object)
33
- self.object2_type = object.class.name
34
- self.object2_text = object.activity_text
35
- self.object2_id = object.id
36
- object
37
- end
38
-
39
- end
40
- end
@@ -1,59 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- class Reset < ActiveRecord::Base
5
-
6
- liquid_methods :code, :url
7
-
8
- belongs_to :user, :polymorphic => true
9
-
10
- validates_presence_of :user, :token
11
-
12
- after_initialize :init, :if => Proc.new { |o| o.new_record? }
13
- after_create :enforce_uniqueness
14
- after_commit :send_email
15
-
16
- def claim
17
- self.claimed_at = Time.zone.now
18
- self.is_active = false
19
- self.save
20
- self.user.update_attributes(:is_active => true, :activated_at => Time.zone.now)
21
- end
22
-
23
- def expired?
24
- !self.is_active
25
- end
26
-
27
- def url
28
- return "#{Rails.application.config.root_url}/admin/reset/#{self.token}" if self.user_type == 'Admin'
29
- return "#{Rails.application.config.root_url}/account/reset/#{self.token}" if self.user_type == 'Customer'
30
- end
31
-
32
- private
33
-
34
- def init
35
- self.token ||= SecureRandom.hex(32).to_s.upcase[0,32]
36
- self.is_active = true
37
- end
38
-
39
- def set_active
40
- self.is_active = true
41
- end
42
-
43
- def enforce_uniqueness
44
- self.user.resets.where('id != ?', self.id).update_all(:is_active => false)
45
- end
46
-
47
- def send_email
48
- if self.user_type == 'Admin'
49
- ApplicationMailer.reset(self).deliver_now!
50
- elsif self.user_type == 'Customer'
51
- template = EmailTemplate.find_by(:code => 'password_reset')
52
- email = EmailDelivery.new(:customer => self.user, :subject => template.subject, :body => template.body)
53
- email.personalize(:customer => self.user, :reset => self)
54
- email.save
55
- end
56
- end
57
-
58
- end
59
- end
@@ -1,9 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- class Story < ActiveRecord::Base
5
-
6
- has_many :activities
7
-
8
- end
9
- end
@@ -1,44 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Backframe
4
- class ActivitySerializer < ActiveModel::Serializer
5
-
6
- cache :key => :object
7
- attributes :id, :subject, :story, :object1, :object2, :created_at, :updated_at
8
-
9
- def subject
10
- if object.subject.present?
11
- { :link => object.subject.activity_link, :photo => (object.subject.photo.present?) ? object.subject.photo.url(:small) : nil, :text => object.subject.full_name }
12
- elsif object.subject_text.present?
13
- { :text => object.subject_text }
14
- else
15
- nil
16
- end
17
- end
18
-
19
- def story
20
- object.story.text
21
- end
22
-
23
- def object1
24
- if object.object1.present?
25
- { :link => object.object1.activity_link, :entity => object.object1.activity_entity, :text => object.object1.activity_text }
26
- elsif object.object1_text.present?
27
- { :text => object.object1_text }
28
- else
29
- nil
30
- end
31
- end
32
-
33
- def object2
34
- if object.object2.present?
35
- { :link => object.object2.activity_link, :entity => object.object2.activity_entity, :text => object.object2.activity_text }
36
- elsif object.object2_text.present?
37
- { :text => object.object2_text }
38
- else
39
- nil
40
- end
41
- end
42
-
43
- end
44
- end
@@ -1,225 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Backframe::ActsAsAPI', type: :controller do
4
- controller do
5
- include Backframe::ActsAsAPI
6
- acts_as_api
7
-
8
- def base_api_url
9
- '/example'
10
- end
11
- end
12
-
13
- describe 'error handlng' do
14
- before { get :index }
15
-
16
- context 'acts_as_resource not found' do
17
- controller do
18
- def index
19
- raise ActiveRecord::RecordNotFound
20
- end
21
- end
22
-
23
- it 'responds with 404 status' do
24
- expect(response.status).to eq 404
25
- end
26
-
27
- it 'responds with JSON body' do
28
- expect(json_response[:error][:status]).to eq 404
29
- expect(json_response[:error][:message]).to be
30
- end
31
- end
32
-
33
- context 'route not found' do
34
- controller do
35
- def index
36
- raise ActionController::RoutingError, ''
37
- end
38
- end
39
-
40
- it 'responds with 404 status' do
41
- expect(response.status).to eq 404
42
- end
43
-
44
- it 'responds with JSON body' do
45
- expect(json_response[:error][:status]).to eq 404
46
- expect(json_response[:error][:message]).to be
47
- end
48
- end
49
-
50
- context 'unauthenticated' do
51
- controller do
52
- def index
53
- raise Backframe::Exceptions::Unauthenticated
54
- end
55
- end
56
-
57
- it 'responds with 401 status' do
58
- expect(response.status).to eq 401
59
- end
60
-
61
- it 'responds with JSON body' do
62
- expect(json_response[:error][:status]).to eq 401
63
- expect(json_response[:error][:message]).to be
64
- end
65
- end
66
-
67
- context 'unauthorized' do
68
- controller do
69
- def index
70
- raise Backframe::Exceptions::Unauthorized
71
- end
72
- end
73
-
74
- it 'responds with 403 status' do
75
- expect(response.status).to eq 403
76
- end
77
-
78
- it 'responds with JSON body' do
79
- expect(json_response[:error][:status]).to eq 403
80
- expect(json_response[:error][:message]).to be
81
- end
82
- end
83
- end
84
-
85
- describe 'headers' do
86
- controller do
87
- def index
88
- render nothing: true
89
- end
90
- end
91
-
92
- it 'responds with Last-Modified header' do
93
- get :index
94
-
95
- # FIXME: Use timecop here
96
- expect(response.headers['Last-Modified']).to eq Time.now.httpdate
97
- end
98
- end
99
-
100
- describe '#page' do
101
- let!(:records) { create_list(:example, 10) }
102
-
103
- controller do
104
- def index
105
- page(Example.all, nil)
106
- end
107
- end
108
-
109
- it 'responds with 200 status' do
110
- get :index, format: :json
111
- expect(response.status).to eq 200
112
- end
113
-
114
- it 'responds with records' do
115
- get :index, format: :json
116
- expect(json_response[:records].length).to eq 10
117
- end
118
-
119
- it 'responds with links' do
120
- get :index, format: :json
121
- expect(json_response[:links]).to be
122
- expect(json_response[:links][:self]).to eq '/example/anonymous.json?page=1'
123
- end
124
-
125
- context 'with pagination params' do
126
- before { get :index, page: 2, per_page: 3, format: :json }
127
-
128
- it 'serializes one page of records' do
129
- expect(json_response[:records].length).to eq 3
130
-
131
- serialized = serialize(Example.sort(Example)[3]).stringify_keys
132
- expect(json_response[:records].first).to eq serialized
133
- end
134
-
135
- it 'includes pagination metadata' do
136
- expect(json_response[:total_records]).to eq 10
137
- expect(json_response[:total_pages]).to eq 4
138
- expect(json_response[:current_page]).to eq 2
139
- end
140
- end
141
-
142
- context 'without pagination params' do
143
- before { get :index, format: :json }
144
-
145
- it 'serializes all records' do
146
- expect(json_response[:records].length).to eq 10
147
-
148
- serialized = serialize(Example.sort(Example).first).stringify_keys
149
- expect(json_response[:records].first).to eq serialized
150
- end
151
-
152
- it 'includes pagination metadata' do
153
- expect(json_response[:total_records]).to eq 10
154
- expect(json_response[:total_pages]).to eq 1
155
- expect(json_response[:current_page]).to eq 1
156
- end
157
- end
158
-
159
- context 'with sort params' do
160
- controller do
161
- def index
162
- page(Example.all)
163
- end
164
- end
165
-
166
- context 'with single param' do
167
- before do
168
- create_list(:example, 10)
169
- get :index, sort: 'a', format: :json
170
- end
171
-
172
- it 'responds with records sorted ascending' do
173
- values = json_response[:records].map { |record| record[:a] }
174
- expect(values).to eq values.sort
175
- end
176
- end
177
-
178
- context 'with negated param' do
179
- before do
180
- create_list(:example, 10)
181
- get :index, sort: '-a', format: :json
182
- end
183
-
184
- it 'responds with records sorted descending' do
185
- values = json_response[:records].map { |record| record[:a] }
186
- expect(values).to eq values.sort.reverse
187
- end
188
- end
189
-
190
- context 'with multiple params' do
191
- before do
192
- create_list(:example, 10, a: 'a')
193
- create_list(:example, 10)
194
- get :index, sort: 'a,b', format: :json
195
- end
196
-
197
- it 'responds with records sorted by both fields' do
198
- values = json_response[:records].map { |record| [record[:a], record[:b]] }
199
- expect(values).to eq values.sort
200
- end
201
- end
202
- end
203
-
204
- context 'with field params' do
205
- let!(:records) { create_list(:example, 10) }
206
-
207
- before { get :index, fields: 'a,b', format: :json }
208
-
209
- it 'only responds with given fields' do
210
- expect(json_response[:records].first).to eq serialize(Example.sort(Example).first, fields: [:a, :b]).stringify_keys
211
- end
212
- end
213
-
214
- context 'with exclude ids params' do
215
- let!(:records) { create_list(:example, 10) }
216
- let(:exclude_ids) { records.take(5).map(&:id).join(',') }
217
-
218
- before { get :index, exclude_ids: exclude_ids, format: :json }
219
-
220
- it 'responds with unexcluded records' do
221
- expect(json_response[:records].length).to eq 5
222
- end
223
- end
224
- end
225
- end