backframe 0.0.49 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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