clever_tap 0.3.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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.rubocop.yml +48 -0
- data/.travis.yml +6 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +164 -0
- data/Rakefile +6 -0
- data/bin/console +8 -0
- data/bin/setup +8 -0
- data/clever_tap.gemspec +33 -0
- data/lib/clever_tap.rb +79 -0
- data/lib/clever_tap/client.rb +113 -0
- data/lib/clever_tap/config.rb +25 -0
- data/lib/clever_tap/entity.rb +87 -0
- data/lib/clever_tap/event.rb +30 -0
- data/lib/clever_tap/failed_response.rb +28 -0
- data/lib/clever_tap/profile.rb +7 -0
- data/lib/clever_tap/response.rb +28 -0
- data/lib/clever_tap/successful_response.rb +30 -0
- data/lib/clever_tap/uploader.rb +72 -0
- data/lib/clever_tap/version.rb +3 -0
- data/lib/clevertap-ruby.rb +1 -0
- data/spec/factories/profile.rb +36 -0
- data/spec/integrations/clever_tap_spec.rb +81 -0
- data/spec/rubocop_spec.rb +12 -0
- data/spec/shared/clever_tap_client.rb +13 -0
- data/spec/shared/entity.rb +105 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/units/clever_tap_client_spec.rb +279 -0
- data/spec/units/clever_tap_spec.rb +88 -0
- data/spec/units/event_spec.rb +43 -0
- data/spec/units/failed_response_spec.rb +31 -0
- data/spec/units/profile_spec.rb +29 -0
- data/spec/units/response_spec.rb +48 -0
- data/spec/units/successful_response_spec.rb +112 -0
- data/spec/units/uploader_spec.rb +129 -0
- data/spec/vcr_cassettes/CleverTap/uploading_a_many_profiles/when_only_some_are_valid/partially_succeds.yml +42 -0
- data/spec/vcr_cassettes/CleverTap/uploading_a_profile/when_is_invalid/fails.yml +41 -0
- data/spec/vcr_cassettes/CleverTap/uploading_a_profile/when_is_valid/succeed.yml +35 -0
- data/spec/vcr_cassettes/CleverTap/uploading_an_event/when_is_valid/succeed.yml +34 -0
- data/spec/vcr_cassettes/CleverTap_Client/_upload/when_upload_records_are_homogenous/and_invalid_records/calls_on_failed_upload_once.yml +38 -0
- data/spec/vcr_cassettes/CleverTap_Client/_upload/when_upload_records_are_homogenous/and_invalid_records/returns_an_array_with_one_failed_Response_object.yml +38 -0
- data/spec/vcr_cassettes/CleverTap_Client/_upload/when_upload_records_are_homogenous/and_valid_records/and_objects_do_not_fit_upload_limit_/calls_on_successful_upload_proc_twice.yml +67 -0
- data/spec/vcr_cassettes/CleverTap_Client/_upload/when_upload_records_are_homogenous/and_valid_records/and_objects_do_not_fit_upload_limit_/returns_an_array_with_two_successful_Response_objects.yml +67 -0
- data/spec/vcr_cassettes/CleverTap_Client/_upload/when_upload_records_are_homogenous/and_valid_records/and_objects_fit_upload_limit_/calls_on_successful_upload_proc_once.yml +36 -0
- data/spec/vcr_cassettes/CleverTap_Client/_upload/when_upload_records_are_homogenous/and_valid_records/and_objects_fit_upload_limit_/returns_an_array_with_one_successful_Response_object.yml +36 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/when_age_is_invalid/behaves_like_validation_failure/failed_to_upload_the_profiles.yml +48 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/when_education_status_is_invalid/behaves_like_validation_failure/failed_to_upload_the_profiles.yml +49 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/when_email_is_invalid/behaves_like_validation_failure/failed_to_upload_the_profiles.yml +48 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/when_employment_status_is_invalid/behaves_like_validation_failure/failed_to_upload_the_profiles.yml +48 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/when_marital_status_is_invalid/behaves_like_validation_failure/failed_to_upload_the_profiles.yml +48 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/when_phone_is_invalid/behaves_like_validation_failure/failed_to_upload_the_profiles.yml +48 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/when_the_creation_date_field_is_missing/behaves_like_validation_failure/failed_to_upload_the_profiles.yml +48 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/with_invalid_credentials/failed_to_upload_the_profiles.yml +36 -0
- data/spec/vcr_cassettes/CleverTap_Uploader/_call/with_valid_data/makes_successful_upload.yml +36 -0
- data/spec/vcr_config.rb +13 -0
- metadata +199 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared/entity'
|
3
|
+
|
4
|
+
RSpec.describe CleverTap::Event do
|
5
|
+
describe '.upload_limit' do
|
6
|
+
subject { described_class.upload_limit }
|
7
|
+
it { is_expected.to eq 1000 }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#to_h' do
|
11
|
+
subject { described_class.new(**params).to_h }
|
12
|
+
|
13
|
+
describe 'choosing `identity`' do
|
14
|
+
it_behaves_like 'choosing identity for', 'event'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'choosing timestamp' do
|
18
|
+
it_behaves_like 'choosing timestamp'
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'event name' do
|
22
|
+
let(:data) { { 'FBID' => '1414', 'Name' => 'John' } }
|
23
|
+
let(:params) { { data: data, identity: 'FBID' } }
|
24
|
+
|
25
|
+
context 'when `name` is not provided' do
|
26
|
+
it { expect { subject }.to raise_error(CleverTap::MissingEventNameError) }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when `name` is provided' do
|
30
|
+
let!(:params_ext) { params.merge!(name: 'Web Event') }
|
31
|
+
it { is_expected.to include 'evtName' => 'Web Event' }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'type' do
|
36
|
+
it_behaves_like 'proper type'
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'data' do
|
40
|
+
it_behaves_like 'constructing data for', 'event'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverTap::FailedResponse do
|
4
|
+
let(:records) { [{ 'id' => 1 }, { 'id' => 2 }] }
|
5
|
+
let(:message) { 'LOL an error' }
|
6
|
+
let(:code) { 401 }
|
7
|
+
|
8
|
+
subject { described_class.new(records: records, message: message, code: code) }
|
9
|
+
|
10
|
+
describe '#status' do
|
11
|
+
it { expect(subject.status).to eq 'fail' }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#success' do
|
15
|
+
it { expect(subject.success).to be false }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#errors' do
|
19
|
+
it do
|
20
|
+
error = { 'status' => 'fail', 'code' => code, 'error' => message }
|
21
|
+
|
22
|
+
expect(subject.errors).to match_array(
|
23
|
+
records.map { |r| error.merge('record' => r) }
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#message' do
|
29
|
+
it { expect(subject.message).to eq message }
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared/entity'
|
3
|
+
|
4
|
+
RSpec.describe CleverTap::Profile do
|
5
|
+
describe '.upload_limit' do
|
6
|
+
subject { described_class.upload_limit }
|
7
|
+
it { is_expected.to eq 100 }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#to_h' do
|
11
|
+
subject { described_class.new(**params).to_h }
|
12
|
+
|
13
|
+
describe 'choosing `identity`' do
|
14
|
+
it_behaves_like 'choosing identity for', 'profile'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'choosing timestamp' do
|
18
|
+
it_behaves_like 'choosing timestamp'
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'type' do
|
22
|
+
it_behaves_like 'proper type'
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'data' do
|
26
|
+
it_behaves_like 'constructing data for', 'profile'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverTap::Response do
|
4
|
+
let(:success) do
|
5
|
+
{ 'status' => 'success', 'processed' => 1, 'unprocessed' => [] }
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:partial) do
|
9
|
+
{
|
10
|
+
'status' => 'success',
|
11
|
+
'processed' => 1,
|
12
|
+
'unprocessed' => [{ '{ "ID" => "5", "Name": "John"}' => 'Some error' }]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:failure) do
|
17
|
+
{
|
18
|
+
'status' => 'fail',
|
19
|
+
'error' => 'Account Id not valid',
|
20
|
+
'code' => 401
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#new' do
|
25
|
+
subject { described_class.new(response) }
|
26
|
+
|
27
|
+
context 'when successful request' do
|
28
|
+
let(:response) { OpenStruct.new(body: success.to_json) }
|
29
|
+
|
30
|
+
it { expect(subject.success).to be true }
|
31
|
+
it { expect(subject.failures).to eq [] }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when partially successful request' do
|
35
|
+
let(:response) { OpenStruct.new(body: partial.to_json) }
|
36
|
+
|
37
|
+
it { expect(subject.success).to be false }
|
38
|
+
it { expect(subject.failures).to eq partial['unprocessed'] }
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when failed request' do
|
42
|
+
let(:response) { OpenStruct.new(body: failure.to_json) }
|
43
|
+
|
44
|
+
it { expect(subject.success).to be false }
|
45
|
+
it { expect(subject.failures).to eq [failure] }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CleverTap::SuccessfulResponse do
|
4
|
+
shared_context 'successful state' do
|
5
|
+
let(:raw_response) do
|
6
|
+
{ 'status' => 'success', 'processed' => 2, 'unprocessed' => [] }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
shared_context 'partial state' do
|
11
|
+
let(:records) { [{ 'id' => 1 }] }
|
12
|
+
let(:raw_response) do
|
13
|
+
{
|
14
|
+
'status' => 'fail',
|
15
|
+
'processed' => 1,
|
16
|
+
'unprocessed' => records.map { |r| { 'record' => r.to_json } }
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
shared_context 'fail state' do
|
22
|
+
let(:records) { [{ 'id' => 1 }, { 'id' => 2 }] }
|
23
|
+
let(:raw_response) do
|
24
|
+
{
|
25
|
+
'status' => 'fail',
|
26
|
+
'processed' => 0,
|
27
|
+
'unprocessed' => records.map { |r| { 'record' => r.to_json } }
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
subject { described_class.new(raw_response) }
|
33
|
+
|
34
|
+
describe '#status' do
|
35
|
+
context 'with successful status' do
|
36
|
+
include_context 'successful state'
|
37
|
+
|
38
|
+
it { expect(subject.status).to eq 'success' }
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with partial status' do
|
42
|
+
include_context 'partial state'
|
43
|
+
|
44
|
+
it { expect(subject.status).to eq 'partial' }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with fail status' do
|
48
|
+
include_context 'fail state'
|
49
|
+
|
50
|
+
it { expect(subject.status).to eq 'fail' }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#success' do
|
55
|
+
context 'with successful status' do
|
56
|
+
include_context 'successful state'
|
57
|
+
|
58
|
+
it { expect(subject.success).to be true }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with partial status' do
|
62
|
+
include_context 'partial state'
|
63
|
+
|
64
|
+
it { expect(subject.success).to be false }
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with fail status' do
|
68
|
+
include_context 'fail state'
|
69
|
+
|
70
|
+
it { expect(subject.success).to be false }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#errors' do
|
75
|
+
context 'with successful status' do
|
76
|
+
include_context 'successful state'
|
77
|
+
|
78
|
+
it { expect(subject.errors).to be_empty }
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'with partial status' do
|
82
|
+
include_context 'partial state'
|
83
|
+
it { expect(subject.errors).to all(include('record')) }
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'with fail status' do
|
87
|
+
include_context 'fail state'
|
88
|
+
|
89
|
+
it { expect(subject.errors).to all(include('record')) }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#message' do
|
94
|
+
context 'with successful status' do
|
95
|
+
include_context 'successful state'
|
96
|
+
|
97
|
+
it { expect(subject.message).to eq '' }
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'with partial status' do
|
101
|
+
include_context 'partial state'
|
102
|
+
|
103
|
+
it { expect(subject.message).to eq '' }
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with fail status' do
|
107
|
+
include_context 'fail state'
|
108
|
+
|
109
|
+
it { expect(subject.message).to eq '' }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'validation failure' do |expected_code|
|
4
|
+
it 'failed to upload the profiles' do
|
5
|
+
result = subject.call(client)
|
6
|
+
body = JSON.parse(result.body)
|
7
|
+
|
8
|
+
aggregate_failures 'failed response' do
|
9
|
+
expect(result.success?).to be_truthy
|
10
|
+
expect(result.status).to eq(200)
|
11
|
+
expect(body).to include('processed' => 0,
|
12
|
+
'status' => 'fail',
|
13
|
+
'unprocessed' => contain_exactly(
|
14
|
+
a_hash_including('code' => expected_code),
|
15
|
+
a_hash_including('code' => expected_code)
|
16
|
+
))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe CleverTap::Uploader, vcr: true do
|
22
|
+
describe '#call' do
|
23
|
+
let(:profile_properties) { %i[id created_at full_name last_name bta] }
|
24
|
+
let(:client) { CleverTap::Client.new(AUTH_ACCOUNT_ID, AUTH_PASSCODE) }
|
25
|
+
|
26
|
+
context 'with valid data' do
|
27
|
+
let(:profiles) { [Profile.build_valid, Profile.build_valid] }
|
28
|
+
|
29
|
+
subject { described_class.new(profiles, identity_field: 'identity') }
|
30
|
+
|
31
|
+
it 'makes successful upload' do
|
32
|
+
result = subject.call(client)
|
33
|
+
body = JSON.parse(result.body)
|
34
|
+
|
35
|
+
aggregate_failures 'success response' do
|
36
|
+
expect(result.success?).to be_truthy
|
37
|
+
expect(result.status).to eq(200)
|
38
|
+
expect(body).to include('processed' => 2, 'unprocessed' => [], 'status' => 'success')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when email is invalid' do
|
44
|
+
let(:profiles) { [Profile.build_valid('Email' => '1234'), Profile.build_valid('Email' => '1234')] }
|
45
|
+
|
46
|
+
subject { described_class.new(profiles, identity_field: 'identity') }
|
47
|
+
|
48
|
+
it_behaves_like 'validation failure', 515
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when phone is invalid' do
|
52
|
+
let(:profiles) { [Profile.build_valid('Phone' => '223'), Profile.build_valid('Phone' => '123')] }
|
53
|
+
|
54
|
+
subject { described_class.new(profiles, identity_field: 'identity') }
|
55
|
+
|
56
|
+
it_behaves_like 'validation failure', 516
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when employment status is invalid' do
|
60
|
+
let(:profiles) { [Profile.build_valid('Employed' => '223'), Profile.build_valid('Employed' => '123')] }
|
61
|
+
|
62
|
+
subject { described_class.new(profiles, identity_field: 'identity') }
|
63
|
+
|
64
|
+
it_behaves_like 'validation failure', 517
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when education status is invalid' do
|
68
|
+
let(:profiles) { [Profile.build_valid('Education' => '223'), Profile.build_valid('Education' => '123')] }
|
69
|
+
|
70
|
+
subject { described_class.new(profiles, identity_field: 'identity') }
|
71
|
+
|
72
|
+
it_behaves_like 'validation failure', 518
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when marital status is invalid' do
|
76
|
+
let(:profiles) { [Profile.build_valid('Married' => '223'), Profile.build_valid('Married' => '123')] }
|
77
|
+
|
78
|
+
subject { described_class.new(profiles, identity_field: 'identity') }
|
79
|
+
|
80
|
+
it_behaves_like 'validation failure', 519
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when age is invalid' do
|
84
|
+
let(:profiles) { [Profile.build_valid('Age' => 'aa'), Profile.build_valid('Age' => 'aa')] }
|
85
|
+
|
86
|
+
subject { described_class.new(profiles, identity_field: 'identity') }
|
87
|
+
|
88
|
+
it_behaves_like 'validation failure', 520
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when the identity field is missing' do
|
92
|
+
let(:profiles) { [Profile.build_valid, Profile.build_valid] }
|
93
|
+
|
94
|
+
subject { described_class.new(profiles, identity_field: 'fake_id') }
|
95
|
+
|
96
|
+
it do
|
97
|
+
expect { subject.call(client) }.to raise_error(RuntimeError, /missing identity field/i)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when the creation date field is missing' do
|
102
|
+
let(:profiles) { [Profile.build_valid, Profile.build_valid] }
|
103
|
+
|
104
|
+
subject do
|
105
|
+
described_class.new(profiles, identity_field: 'identity', date_field: 'fake_created_at')
|
106
|
+
end
|
107
|
+
|
108
|
+
it_behaves_like 'validation failure', 525
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with invalid credentials' do
|
112
|
+
let(:client) { CleverTap::Client.new('fake-id', 'fake-pass') }
|
113
|
+
subject { described_class.new([Profile.build_valid], identity_field: 'identity') }
|
114
|
+
|
115
|
+
it 'failed to upload the profiles' do
|
116
|
+
result = subject.call(client)
|
117
|
+
body = JSON.parse(result.body)
|
118
|
+
|
119
|
+
aggregate_failures 'failed response' do
|
120
|
+
expect(result.success?).to be_falsy
|
121
|
+
expect(result.status).to eq(401)
|
122
|
+
expect(body).to include('code' => 401,
|
123
|
+
'status' => 'fail',
|
124
|
+
'error' => matching(/account id/i))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.clevertap.com/1/upload
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"d":[{"identity":"3","ts":1521649274,"type":"profile","profileData":{"identity":3,"created_at":"2018-03-21
|
9
|
+
18:21:14 +0200","Name":"John Rush","Email":"example@gmail.com","Gender":"M","Phone":"+35922333232","Employed":"Y","Education":"Graduate","Married":"Y","Age":"18"}},{"identity":"4","ts":1521649274,"type":"profile","profileData":{"identity":4,"created_at":"2018-03-21
|
10
|
+
18:21:14 +0200","Name":"John Rush","Email":"$$$$$","Gender":"M","Phone":"+35922333232","Employed":"Y","Education":"Graduate","Married":"Y","Age":"18"}}]}'
|
11
|
+
headers:
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
X-CleverTap-Account-Id:
|
15
|
+
- fake_account_id
|
16
|
+
X-CleverTap-Passcode:
|
17
|
+
- fake_passcode
|
18
|
+
User-Agent:
|
19
|
+
- Faraday v0.14.0
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
content-type:
|
26
|
+
- application/json;charset=utf-8
|
27
|
+
content-length:
|
28
|
+
- '505'
|
29
|
+
connection:
|
30
|
+
- Close
|
31
|
+
body:
|
32
|
+
encoding: UTF-8
|
33
|
+
string: '{ "status" : "partial" , "processed" : 1 , "unprocessed" : [ { "status"
|
34
|
+
: "fail" , "code" : 515 , "error" : "Profile data is incorrect. Email is not
|
35
|
+
valid.Skipped record number : 2" , "record" : { "identity" : "4" , "ts" :
|
36
|
+
1521649274 , "type" : "profile" , "profileData" : { "identity" : 4 , "created_at"
|
37
|
+
: "2018-03-21 18:21:14 +0200" , "Name" : "John Rush" , "Email" : "$$$$$" ,
|
38
|
+
"Gender" : "M" , "Phone" : "+35922333232" , "Employed" : "Y" , "Education"
|
39
|
+
: "Graduate" , "Married" : "Y" , "Age" : "18"}}}]}'
|
40
|
+
http_version:
|
41
|
+
recorded_at: Wed, 21 Mar 2018 16:21:15 GMT
|
42
|
+
recorded_with: VCR 4.0.0
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.clevertap.com/1/upload
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"d":[{"identity":"2","ts":1521649274,"type":"profile","profileData":{"identity":2,"created_at":"2018-03-21
|
9
|
+
18:21:14 +0200","Name":"John Rush","Email":"$$$$$","Gender":"M","Phone":"+35922333232","Employed":"Y","Education":"Graduate","Married":"Y","Age":"18"}}]}'
|
10
|
+
headers:
|
11
|
+
Content-Type:
|
12
|
+
- application/json
|
13
|
+
X-CleverTap-Account-Id:
|
14
|
+
- fake_account_id
|
15
|
+
X-CleverTap-Passcode:
|
16
|
+
- fake_passcode
|
17
|
+
User-Agent:
|
18
|
+
- Faraday v0.14.0
|
19
|
+
response:
|
20
|
+
status:
|
21
|
+
code: 200
|
22
|
+
message: OK
|
23
|
+
headers:
|
24
|
+
content-type:
|
25
|
+
- application/json;charset=utf-8
|
26
|
+
content-length:
|
27
|
+
- '502'
|
28
|
+
connection:
|
29
|
+
- Close
|
30
|
+
body:
|
31
|
+
encoding: UTF-8
|
32
|
+
string: '{ "status" : "fail" , "processed" : 0 , "unprocessed" : [ { "status"
|
33
|
+
: "fail" , "code" : 515 , "error" : "Profile data is incorrect. Email is not
|
34
|
+
valid.Skipped record number : 1" , "record" : { "identity" : "2" , "ts" :
|
35
|
+
1521649274 , "type" : "profile" , "profileData" : { "identity" : 2 , "created_at"
|
36
|
+
: "2018-03-21 18:21:14 +0200" , "Name" : "John Rush" , "Email" : "$$$$$" ,
|
37
|
+
"Gender" : "M" , "Phone" : "+35922333232" , "Employed" : "Y" , "Education"
|
38
|
+
: "Graduate" , "Married" : "Y" , "Age" : "18"}}}]}'
|
39
|
+
http_version:
|
40
|
+
recorded_at: Wed, 21 Mar 2018 16:21:14 GMT
|
41
|
+
recorded_with: VCR 4.0.0
|