rack-signature 0.0.8 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +50 -1
- data/lib/rack/signature.rb +4 -0
- data/lib/rack/signature/build_message.rb +38 -7
- data/lib/rack/signature/build_post_body.rb +28 -0
- data/lib/rack/signature/deep_merge.rb +57 -0
- data/lib/rack/signature/sort_query_params.rb +45 -0
- data/lib/rack/signature/test_helpers.rb +19 -14
- data/lib/rack/signature/verify.rb +42 -11
- data/lib/rack/signature/version.rb +2 -2
- data/rack-signature.gemspec +1 -0
- data/test/array_of_hashes.json +32 -0
- data/test/build_message_test.rb +40 -4
- data/test/build_post_body_test.rb +24 -0
- data/test/data.json +61 -0
- data/test/deep_merge_test.rb +76 -0
- data/test/ordered_json_data.json +1 -0
- data/test/sort_query_params_test.rb +253 -0
- data/test/test_helper.rb +59 -0
- data/test/verify_test.rb +237 -57
- metadata +34 -4
data/test/build_message_test.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
-
require_relative '
|
2
|
-
require '
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'json'
|
3
3
|
|
4
4
|
module Rack::Signature
|
5
5
|
class BuildMessageTest < MiniTest::Unit::TestCase
|
6
|
+
include TestHelper
|
7
|
+
|
8
|
+
def test_get_query
|
9
|
+
env = Rack::MockRequest.env_for(
|
10
|
+
"http://localhost:3000/api/register",
|
11
|
+
"CONTENT_TYPE" => 'application/json',
|
12
|
+
'REQUEST_METHOD' => 'POST',
|
13
|
+
input: { 'email' => 'demo@example.com', 'password' => '123456' }.to_json)
|
14
|
+
|
15
|
+
assert_equal 'POST/api/registerlocalhost{"email":"demo@example.com","password":"123456"}', BuildMessage.new(env).build!
|
16
|
+
end
|
6
17
|
|
7
18
|
def test_build_with_a_valid_request
|
8
19
|
env = Rack::MockRequest.env_for(
|
@@ -17,12 +28,37 @@ module Rack::Signature
|
|
17
28
|
"http://example.com/api/login",
|
18
29
|
"Content-Type" => "application/json",
|
19
30
|
"REQUEST_METHOD" => "POST",
|
20
|
-
input:
|
31
|
+
input: {'passord' => '123456', 'email' => 'me@home.com', 'age' => 1}.to_json
|
21
32
|
)
|
22
33
|
|
23
|
-
|
34
|
+
message = 'POST/api/loginexample.com{"age":1,"email":"me@home.com","passord":"123456"}'
|
35
|
+
assert_equal message,
|
24
36
|
BuildMessage.new(env).build!
|
25
37
|
end
|
26
38
|
|
39
|
+
def test_query_string
|
40
|
+
env = Rack::MockRequest.env_for(
|
41
|
+
"http://example.com/api/login?password=elf&email=santa@claus.com&name=santa",
|
42
|
+
"Content-Type" => "application/json",
|
43
|
+
"REQUEST_METHOD" => "GET"
|
44
|
+
)
|
45
|
+
|
46
|
+
assert_equal "GET/api/loginexample.comemail=santa@claus.com&name=santa&password=elf",
|
47
|
+
BuildMessage.new(env).build!
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_nested_json_structure
|
51
|
+
env = Rack::MockRequest.env_for(
|
52
|
+
"http://example.com/api/create?name=me", {
|
53
|
+
method: 'POST',
|
54
|
+
content_type: 'application/json',
|
55
|
+
input: read_json('data')
|
56
|
+
})
|
57
|
+
ordered_json = read_json('ordered_json_data').chomp
|
58
|
+
message = "POST/api/createexample.com#{ordered_json}"
|
59
|
+
|
60
|
+
assert_equal message, BuildMessage.new(env).build!
|
61
|
+
end
|
62
|
+
|
27
63
|
end
|
28
64
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative '../lib/rack/signature/build_post_body'
|
2
|
+
require_relative '../lib/rack/signature/sort_query_params'
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
module Rack::Signature
|
6
|
+
class BuildPostBodyTest < MiniTest::Unit::TestCase
|
7
|
+
include TestHelper
|
8
|
+
|
9
|
+
def hash
|
10
|
+
@hash ||= JSON.parse(read_json('data'))
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
BuildPostBody.new(hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_sorting_data
|
18
|
+
expected = {"fitting"=>{"club_swing_data"=>[{"driver"=>{"backspin"=>"2", "ball_speed"=>"a", "deviation_angle"=>"2.3", "launch_angle"=>"3.2", "mode"=>"b", "slidespin"=>"1"}}], "distributor"=>"Big 5", "golfer"=>{"agreedToPromotion"=>"false", "country"=>"USA", "email"=>"mice@mice.com", "firstName"=>"Johnny", "gender"=>"male", "lastName"=>"Bravo", "zipcode"=>"938383"}, "location"=>[32.694866, -116.630859], "measurements"=>{"clubPreferences"=>{"shaftFlexDriver"=>"b"}, "golfer"=>{"handicap"=>"8", "height"=>"6.1", "rightHanded"=>"true", "roundsPerMonth"=>"9", "shotShape"=>"b"}}, "recommendations"=>[{"adjustments"=>{"face_angle"=>"angle", "loft"=>"f", "shaft_flex"=>"shaft flex", "shaft_model"=>"club", "shot_shape"=>"circle"}, "club_name"=>"g", "sku"=>"h"}], "trajectory"=>{"carry"=>"two", "coordinates"=>[{"time"=>"12345", "x"=>"3.1", "y"=>"2.1", "z"=>"1.1"}], "deviation"=>"one", "peakHeight"=>"tree"}}}
|
19
|
+
|
20
|
+
assert_equal expected, build.sort_post_body
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/test/data.json
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
{ "fitting": {
|
2
|
+
"golfer": {
|
3
|
+
"firstName": "Johnny",
|
4
|
+
"lastName": "Bravo",
|
5
|
+
"email": "mice@mice.com",
|
6
|
+
"gender": "male",
|
7
|
+
"country": "USA",
|
8
|
+
"zipcode": "938383",
|
9
|
+
"agreedToPromotion": "false"
|
10
|
+
},
|
11
|
+
"measurements": {
|
12
|
+
"golfer": {
|
13
|
+
"rightHanded": "true",
|
14
|
+
"height": "6.1",
|
15
|
+
"roundsPerMonth": "9",
|
16
|
+
"handicap": "8",
|
17
|
+
"shotShape": "b"
|
18
|
+
},
|
19
|
+
"clubPreferences": {
|
20
|
+
"shaftFlexDriver": "b"
|
21
|
+
}
|
22
|
+
},
|
23
|
+
"club_swing_data": [{
|
24
|
+
"driver": {
|
25
|
+
"slidespin": "1",
|
26
|
+
"mode": "b",
|
27
|
+
"launch_angle": "3.2",
|
28
|
+
"deviation_angle": "2.3",
|
29
|
+
"backspin": "2",
|
30
|
+
"ball_speed": "a"
|
31
|
+
}
|
32
|
+
}],
|
33
|
+
"recommendations": [
|
34
|
+
{
|
35
|
+
"sku": "h",
|
36
|
+
"club_name": "g",
|
37
|
+
"adjustments": {
|
38
|
+
"loft": "f",
|
39
|
+
"shaft_flex": "shaft flex",
|
40
|
+
"face_angle": "angle",
|
41
|
+
"shot_shape": "circle",
|
42
|
+
"shaft_model": "club"
|
43
|
+
}
|
44
|
+
}],
|
45
|
+
"trajectory": {
|
46
|
+
"peakHeight": "tree",
|
47
|
+
"deviation": "one",
|
48
|
+
"carry": "two",
|
49
|
+
"coordinates": [
|
50
|
+
{
|
51
|
+
"z": "1.1",
|
52
|
+
"x": "3.1",
|
53
|
+
"y": "2.1",
|
54
|
+
"time": "12345"
|
55
|
+
}
|
56
|
+
]
|
57
|
+
},
|
58
|
+
"distributor": "Big 5",
|
59
|
+
"location": [32.694866,-116.630859]
|
60
|
+
}
|
61
|
+
}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative '../lib/rack/signature/deep_merge'
|
2
|
+
require_relative 'test_helper'
|
3
|
+
|
4
|
+
module Rack::Signature
|
5
|
+
describe DeepMerge do
|
6
|
+
include TestHelper
|
7
|
+
|
8
|
+
it 'will merge a sorted hash into a string' do
|
9
|
+
DeepMerge.new(sorted_nested_hash).merge!.must_equal sorted_nested_string
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'will merge a sorted hash into a string when the hash is a simple hash' do
|
13
|
+
expected = "age=22&name=john"
|
14
|
+
DeepMerge.new({'age' => 22, 'name' => 'john'}).merge!.must_equal expected
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'will merge a simple nested hash into a string' do
|
18
|
+
expected = "age=22&person[name]=john"
|
19
|
+
DeepMerge.new({'age' => 22, 'person' => {'name' => 'john'}}).merge!.must_equal expected
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'will merge a hash that has a single nested hash, but with multiple values' do
|
23
|
+
expected = "age=22&person[first_name]=john&person[last_name]=smith"
|
24
|
+
DeepMerge.new({'age' => 22, 'person' => {'first_name' => 'john', 'last_name' => 'smith'}}).merge!.must_equal expected
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'will merge a hash that has two levels of nesting' do
|
28
|
+
expected = "age=22&person[given_name][first_name]=john&person[given_name][last_name]=smith"
|
29
|
+
DeepMerge.new({'age' => 22, 'person' => {'given_name' => {'first_name' => 'john', 'last_name' => 'smith'}}}).merge!.must_equal expected
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'will merge a deeply nested hash' do
|
33
|
+
actual = {'id' => 22,
|
34
|
+
'person' => {
|
35
|
+
'age' => 22, 'given_name' => {'first_name' => 'john', 'last_name' => 'smith'}
|
36
|
+
},
|
37
|
+
'license' => false,
|
38
|
+
'birth' => { 'country' => 'USA', 'state' => 'California', 'address' => {
|
39
|
+
"street" => '123', 'street2' => '456', 'city' => 'san diego', 'further-nesting' => { 'name' => 'smith' }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
expected = "id=22&person[age]=22&person[given_name][first_name]=john&person[given_name][last_name]=smith&license=false&birth[country]=USA&birth[state]=California&birth[address][street]=123&birth[address][street2]=456&birth[address][city]=san diego&birth[address][further-nesting][name]=smith"
|
44
|
+
|
45
|
+
DeepMerge.new(actual).merge!.must_equal expected
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'will merge a hash with an array inside the hash' do
|
49
|
+
actual = { 'id' => 22, 'person' => { 'family' => [ { 'father' => 'John Smith Sr.', 'alive' => true }, { 'mother' => 'Marie Smith', 'alive' => false }, { 'siblings' => 2, 'alive' => true }], 'given_name' => 'John Smith', 'last_name' => 'Smith', 'first_name' => 'John' } }
|
50
|
+
expected = 'id=22&person[family][][father]=John Smith Sr.&person[family][][alive]=true&person[family][][mother]=Marie Smith&person[family][][alive]=false&person[family][][siblings]=2&person[family][][alive]=true&person[given_name]=John Smith&person[last_name]=Smith&person[first_name]=John'
|
51
|
+
|
52
|
+
DeepMerge.new(actual).merge!.must_equal expected
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'will merge a hash that has an array at the top level' do
|
56
|
+
actual = { 'company' => 'x', 'people' => [ {'name' => 'John Smith', 'age' => 22}, {'name' => 'Marie Smith', 'age' => 24}, {'name' => 'Bob Smith', 'age' => 27} ], 'family' => true }
|
57
|
+
expected = 'company=x&people[][name]=John Smith&people[][age]=22&people[][name]=Marie Smith&people[][age]=24&people[][name]=Bob Smith&people[][age]=27&family=true'
|
58
|
+
DeepMerge.new(actual).merge!.must_equal expected
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'will merge a hash that includes multiple arrays nested' do
|
62
|
+
actual = { 'tree' => [ { 'family' => {'sir_name' => 'smith', 'root' => 'Joseph Smith', 'children' => [ { 'last_name' => 'Wayne', 'number_of_children' => 7} ] } } ] }
|
63
|
+
expected = "tree[][family][sir_name]=smith&tree[][family][root]=Joseph Smith&tree[][family][children][][last_name]=Wayne&tree[][family][children][][number_of_children]=7"
|
64
|
+
|
65
|
+
DeepMerge.new(actual).merge!.must_equal expected
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'will merge a hash that includes nested array of arrays' do
|
69
|
+
actual = {'tree' => [[ { 'leaves' => 'brown', 'type' => 'pine', 'attributes' => { 'height' => '26 feet', 'age' => '32 years' }}], {'count' => 229} ]}
|
70
|
+
expected = "tree[][][leaves]=brown&tree[][][type]=pine&tree[][][attributes][height]=26 feet&tree[][][attributes][age]=32 years&tree[][count]=229"
|
71
|
+
|
72
|
+
DeepMerge.new(actual).merge!.must_equal expected
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"fitting":{"club_swing_data":[{"driver":{"backspin":"2","ball_speed":"a","deviation_angle":"2.3","launch_angle":"3.2","mode":"b","slidespin":"1"}}],"distributor":"Big 5","golfer":{"agreedToPromotion":"false","country":"USA","email":"mice@mice.com","firstName":"Johnny","gender":"male","lastName":"Bravo","zipcode":"938383"},"location":[32.694866,-116.630859],"measurements":{"clubPreferences":{"shaftFlexDriver":"b"},"golfer":{"handicap":"8","height":"6.1","rightHanded":"true","roundsPerMonth":"9","shotShape":"b"}},"recommendations":[{"adjustments":{"face_angle":"angle","loft":"f","shaft_flex":"shaft flex","shaft_model":"club","shot_shape":"circle"},"club_name":"g","sku":"h"}],"trajectory":{"carry":"two","coordinates":[{"time":"12345","x":"3.1","y":"2.1","z":"1.1"}],"deviation":"one","peakHeight":"tree"}}}
|
@@ -0,0 +1,253 @@
|
|
1
|
+
require_relative '../lib/rack/signature/sort_query_params'
|
2
|
+
require_relative 'test_helper'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Rack::Signature
|
6
|
+
describe SortQueryParams do
|
7
|
+
include TestHelper
|
8
|
+
|
9
|
+
it 'will sort a loaded json file' do
|
10
|
+
json = read_json('data')
|
11
|
+
hash = JSON.parse(json)
|
12
|
+
|
13
|
+
ordered_json = read_json('ordered_json_data')
|
14
|
+
ordered_json_hash = JSON.parse(ordered_json)
|
15
|
+
|
16
|
+
assert_equal ordered_json_hash, SortQueryParams.new(hash).order
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'will sort a large data set' do
|
20
|
+
assert_equal expected_data, SortQueryParams.new(actual_data).order
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'will sort a simple hash by keys only' do
|
24
|
+
expected = { age: 99, first_name: 'john', last_name: 'smith'}
|
25
|
+
assert_equal expected, SortQueryParams.new({last_name: 'smith', first_name: 'john', age: 99}).order
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'will handle a simple array' do
|
29
|
+
actual = {"location" => [32, 34], "angle" => 3 }
|
30
|
+
expected = {"angle" => 3, "location" => [32, 34] }
|
31
|
+
|
32
|
+
assert_equal expected, SortQueryParams.new(actual).order
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can handle multiple keys of the same name when sorting' do
|
36
|
+
actual = { data: [ {person: { name: 'john', age: 12 }}, {person: { name: 'bill', age: 77 }}]}
|
37
|
+
expected = { data: [ {person: { age: 12, name: 'john' }}, {person: { age: 77, name: 'bill' }}]}
|
38
|
+
|
39
|
+
assert_equal expected, SortQueryParams.new(actual).order
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'will handle array of hashes' do
|
43
|
+
json = read_json('array_of_hashes')
|
44
|
+
unsorted = JSON.parse(json)
|
45
|
+
sorted = {"club_swing_data"=>[{"backspin"=>"3000.0", "ball_speed"=>"130.0", "club"=>"driver", "deviation_angle"=>"0.0", "launch_angle"=>"10.0", "mode"=>"manual", "shot"=>1, "slidespin"=>"0.0"}, {"backspin"=>"3000.0", "ball_speed"=>"130.0", "club"=>"driver", "deviation_angle"=>"0.0", "launch_angle"=>"10.0", "mode"=>"manual", "shot"=>2, "slidespin"=>"0.0"}, {"backspin"=>"3000.0", "ball_speed"=>"130.0", "club"=>"driver", "deviation_angle"=>"0.0", "launch_angle"=>"10.0", "mode"=>"manual", "shot"=>3, "slidespin"=>"0.0"}]}
|
46
|
+
|
47
|
+
assert_equal sorted, SortQueryParams.new(unsorted).order
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'will sort array of hashes' do
|
51
|
+
actual = {
|
52
|
+
"recommendations" => [{
|
53
|
+
"sku" =>"h",
|
54
|
+
"club_name" =>"g",
|
55
|
+
"adjustments" => {
|
56
|
+
"shaft_model" => "club",
|
57
|
+
"shot_shape" => "circle",
|
58
|
+
"shaft_flex" => "shaft flex",
|
59
|
+
"loft" => "f",
|
60
|
+
"face_angle" => "angle",
|
61
|
+
},
|
62
|
+
}],
|
63
|
+
"distributor" => "Big 5",
|
64
|
+
"golfer" => {
|
65
|
+
"agreedToPromotion" =>"false",
|
66
|
+
"country" =>"USA",
|
67
|
+
"email" =>"mice@mice.com",
|
68
|
+
"firstName" =>"Johnny",
|
69
|
+
"gender" =>"male",
|
70
|
+
"lastName" =>"Bravo",
|
71
|
+
"zipcode" =>"938383"
|
72
|
+
},
|
73
|
+
}
|
74
|
+
expected = {
|
75
|
+
"distributor" => "Big 5",
|
76
|
+
"golfer" => {
|
77
|
+
"agreedToPromotion" =>"false",
|
78
|
+
"country" =>"USA",
|
79
|
+
"email" =>"mice@mice.com",
|
80
|
+
"firstName" =>"Johnny",
|
81
|
+
"gender" =>"male",
|
82
|
+
"lastName" =>"Bravo",
|
83
|
+
"zipcode" =>"938383"
|
84
|
+
},
|
85
|
+
"recommendations" => [{
|
86
|
+
"adjustments" => {
|
87
|
+
"face_angle" => "angle",
|
88
|
+
"loft" => "f",
|
89
|
+
"shaft_flex" => "shaft flex",
|
90
|
+
"shaft_model" => "club",
|
91
|
+
"shot_shape" => "circle",
|
92
|
+
},
|
93
|
+
"club_name" =>"g",
|
94
|
+
"sku" =>"h"
|
95
|
+
}]
|
96
|
+
}
|
97
|
+
|
98
|
+
assert_equal expected, SortQueryParams.new(actual).order
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'will sort a rooted hash' do
|
102
|
+
actual = {
|
103
|
+
"fitting" => {
|
104
|
+
"measurements" => {
|
105
|
+
"golfer" => {
|
106
|
+
"shotShape" =>"b",
|
107
|
+
"height" =>"6.1",
|
108
|
+
"rightHanded" =>"true",
|
109
|
+
"roundsPerMonth" =>"9",
|
110
|
+
"handicap" =>"8"
|
111
|
+
},
|
112
|
+
"clubPreferences" => {"shaftFlexDriver"=>"b"}
|
113
|
+
},
|
114
|
+
"club_swing_data" =>
|
115
|
+
[{
|
116
|
+
"driver" => {
|
117
|
+
"slidespin" =>"1",
|
118
|
+
"ball_speed" =>"a",
|
119
|
+
"mode" =>"b",
|
120
|
+
"launch_angle" =>"3.2",
|
121
|
+
"deviation_angle" =>"2.3",
|
122
|
+
"backspin" =>"2"
|
123
|
+
}}]
|
124
|
+
}}
|
125
|
+
|
126
|
+
expected = {
|
127
|
+
"fitting" => {
|
128
|
+
"club_swing_data" =>
|
129
|
+
[{
|
130
|
+
"driver" => {
|
131
|
+
"backspin" =>"2",
|
132
|
+
"ball_speed" =>"a",
|
133
|
+
"deviation_angle" =>"2.3",
|
134
|
+
"launch_angle" =>"3.2",
|
135
|
+
"mode" =>"b",
|
136
|
+
"slidespin" =>"1"
|
137
|
+
}}],
|
138
|
+
"measurements" => {
|
139
|
+
"clubPreferences" => {"shaftFlexDriver"=>"b"},
|
140
|
+
"golfer" => {
|
141
|
+
"handicap" =>"8",
|
142
|
+
"height" =>"6.1",
|
143
|
+
"rightHanded" =>"true",
|
144
|
+
"roundsPerMonth" =>"9",
|
145
|
+
"shotShape" =>"b"
|
146
|
+
}
|
147
|
+
}
|
148
|
+
}}
|
149
|
+
|
150
|
+
assert_equal expected, SortQueryParams.new(actual).order
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def expected_data
|
155
|
+
{"fitting" => {
|
156
|
+
"club_swing_data" => [
|
157
|
+
{
|
158
|
+
"driver" => {
|
159
|
+
"backspin" =>"2",
|
160
|
+
"ball_speed" =>"a",
|
161
|
+
"deviation_angle" =>"2.3",
|
162
|
+
"launch_angle" =>"3.2",
|
163
|
+
"mode" =>"b",
|
164
|
+
"slidespin" =>"1"
|
165
|
+
}}
|
166
|
+
],
|
167
|
+
"distributor" => "Big 5",
|
168
|
+
"golfer" => {
|
169
|
+
"agreedToPromotion" =>"false",
|
170
|
+
"country" =>"USA",
|
171
|
+
"email" =>"mice@mice.com",
|
172
|
+
"firstName" =>"Johnny",
|
173
|
+
"gender" =>"male",
|
174
|
+
"lastName" =>"Bravo",
|
175
|
+
"zipcode" =>"938383"
|
176
|
+
},
|
177
|
+
"location" => [32.694866, -116.630859],
|
178
|
+
"measurements" => {
|
179
|
+
"clubPreferences" => {"shaftFlexDriver"=>"b"},
|
180
|
+
"golfer" => {
|
181
|
+
"handicap" =>"8",
|
182
|
+
"height" =>"6.1",
|
183
|
+
"rightHanded" =>"true",
|
184
|
+
"roundsPerMonth" =>"9",
|
185
|
+
"shotShape" =>"b"
|
186
|
+
}
|
187
|
+
},
|
188
|
+
"recommendations" => [{
|
189
|
+
"adjustments" => {
|
190
|
+
"face_angle" => "angle",
|
191
|
+
"loft" => "f",
|
192
|
+
"shaft_flex" => "shaft flex",
|
193
|
+
"shaft_model" => "club",
|
194
|
+
"shot_shape" => "circle",
|
195
|
+
},
|
196
|
+
"club_name" =>"g",
|
197
|
+
"sku" =>"h"
|
198
|
+
}]
|
199
|
+
}}
|
200
|
+
end
|
201
|
+
|
202
|
+
def actual_data
|
203
|
+
{"fitting" => {
|
204
|
+
"golfer" => {
|
205
|
+
"firstName" =>"Johnny",
|
206
|
+
"email" =>"mice@mice.com",
|
207
|
+
"agreedToPromotion" =>"false",
|
208
|
+
"zipcode" =>"938383",
|
209
|
+
"lastName" =>"Bravo",
|
210
|
+
"gender" =>"male",
|
211
|
+
"country" =>"USA",
|
212
|
+
},
|
213
|
+
"measurements" => {
|
214
|
+
"clubPreferences" => {"shaftFlexDriver"=>"b"},
|
215
|
+
"golfer" => {
|
216
|
+
"rightHanded" =>"true",
|
217
|
+
"height" =>"6.1",
|
218
|
+
"roundsPerMonth" =>"9",
|
219
|
+
"shotShape" =>"b",
|
220
|
+
"handicap" =>"8",
|
221
|
+
}
|
222
|
+
},
|
223
|
+
"location" => [32.694866, -116.630859],
|
224
|
+
"recommendations" => [{
|
225
|
+
"club_name" =>"g",
|
226
|
+
"adjustments" => {
|
227
|
+
"shot_shape" => "circle",
|
228
|
+
"loft" => "f",
|
229
|
+
"shaft_model" => "club",
|
230
|
+
"shaft_flex" => "shaft flex",
|
231
|
+
"face_angle" => "angle",
|
232
|
+
},
|
233
|
+
"sku" =>"h"
|
234
|
+
}
|
235
|
+
],
|
236
|
+
"distributor" => "Big 5",
|
237
|
+
"club_swing_data" => [
|
238
|
+
{
|
239
|
+
"driver" => {
|
240
|
+
"backspin" =>"2",
|
241
|
+
"ball_speed" =>"a",
|
242
|
+
"deviation_angle" =>"2.3",
|
243
|
+
"launch_angle" =>"3.2",
|
244
|
+
"mode" =>"b",
|
245
|
+
"slidespin" =>"1"
|
246
|
+
}}
|
247
|
+
]
|
248
|
+
}}
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|