vwo-sdk 1.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/lib/vwo.rb +348 -0
- data/lib/vwo/constants.rb +63 -0
- data/lib/vwo/core/bucketer.rb +177 -0
- data/lib/vwo/core/variation_decider.rb +308 -0
- data/lib/vwo/enums.rb +115 -0
- data/lib/vwo/logger.rb +37 -0
- data/lib/vwo/schemas/settings_file.rb +102 -0
- data/lib/vwo/services/event_dispatcher.rb +82 -0
- data/lib/vwo/services/settings_file_manager.rb +84 -0
- data/lib/vwo/services/settings_file_processor.rb +54 -0
- data/lib/vwo/user_storage.rb +36 -0
- data/lib/vwo/utils/campaign.rb +125 -0
- data/lib/vwo/utils/function.rb +39 -0
- data/lib/vwo/utils/impression.rb +98 -0
- data/lib/vwo/utils/request.rb +31 -0
- data/lib/vwo/utils/uuid.rb +93 -0
- data/lib/vwo/utils/validations.rb +56 -0
- metadata +117 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright 2019 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# frozen_string_literal: true
|
16
|
+
|
17
|
+
require_relative '../logger'
|
18
|
+
require_relative '../enums'
|
19
|
+
require_relative '../constants'
|
20
|
+
|
21
|
+
# Utility module for helper math and random functions
|
22
|
+
class VWO
|
23
|
+
module Utils
|
24
|
+
module Function
|
25
|
+
include VWO::Enums
|
26
|
+
include VWO::CONSTANTS
|
27
|
+
|
28
|
+
# @return[Float]
|
29
|
+
def get_random_number
|
30
|
+
rand
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return[Integer]
|
34
|
+
def get_current_unix_timestamp
|
35
|
+
Time.now.to_i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# Copyright 2019 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# frozen_string_literal: true
|
16
|
+
|
17
|
+
require 'json'
|
18
|
+
require 'cgi'
|
19
|
+
require_relative '../logger'
|
20
|
+
require_relative '../enums'
|
21
|
+
require_relative '../constants'
|
22
|
+
require_relative 'function'
|
23
|
+
require_relative 'uuid'
|
24
|
+
|
25
|
+
# Creates the impression from the arguments passed
|
26
|
+
class VWO
|
27
|
+
module Utils
|
28
|
+
module Impression
|
29
|
+
include VWO::Enums
|
30
|
+
include VWO::CONSTANTS
|
31
|
+
include VWO::Utils::Function
|
32
|
+
include UUID
|
33
|
+
|
34
|
+
# Creates the impression from the arguments passed
|
35
|
+
#
|
36
|
+
# @param[Hash] :settings_file Settings file object
|
37
|
+
# @param[String] :campaign_id Campaign identifier
|
38
|
+
# @param[String] :variation_id Variation identifier
|
39
|
+
# @param[String] :user_id User identifier
|
40
|
+
# @param[String] :goal_id Goal identifier, if building track impression
|
41
|
+
# @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
|
42
|
+
#
|
43
|
+
# @return[nil|Hash] None if campaign ID or variation ID is invalid,
|
44
|
+
# Else Properties(dict)
|
45
|
+
def create_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
|
46
|
+
return unless valid_number?(campaign_id) && valid_string?(user_id)
|
47
|
+
|
48
|
+
is_track_user_api = true
|
49
|
+
is_track_user_api = false unless goal_id.nil?
|
50
|
+
account_id = settings_file['accountId']
|
51
|
+
|
52
|
+
impression = {
|
53
|
+
account_id: account_id,
|
54
|
+
experiment_id: campaign_id,
|
55
|
+
ap: PLATFORM,
|
56
|
+
uId: CGI.escape(user_id.encode('utf-8')),
|
57
|
+
combination: variation_id,
|
58
|
+
random: get_random_number,
|
59
|
+
sId: get_current_unix_timestamp,
|
60
|
+
u: generator_for(user_id, account_id)
|
61
|
+
}
|
62
|
+
# Version and SDK constants
|
63
|
+
sdk_version = Gem.loaded_specs['vwo_sdk'] ? Gem.loaded_specs['vwo_sdk'].version : VWO::SDK_VERSION
|
64
|
+
impression['sdk'] = 'ruby'
|
65
|
+
impression['sdk-v'] = sdk_version
|
66
|
+
|
67
|
+
url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL
|
68
|
+
logger = VWO::Logger.get_instance
|
69
|
+
|
70
|
+
if is_track_user_api
|
71
|
+
impression['ed'] = JSON.generate(p: 'server')
|
72
|
+
impression['url'] = "#{url}#{ENDPOINTS::TRACK_USER}"
|
73
|
+
logger.log(
|
74
|
+
LogLevelEnum::DEBUG,
|
75
|
+
format(
|
76
|
+
LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_USER,
|
77
|
+
file: FileNameEnum::ImpressionUtil,
|
78
|
+
properties: JSON.generate(impression)
|
79
|
+
)
|
80
|
+
)
|
81
|
+
else
|
82
|
+
impression['url'] = url + ENDPOINTS::TRACK_GOAL
|
83
|
+
impression['goal_id'] = goal_id
|
84
|
+
impression['r'] = revenue if revenue
|
85
|
+
logger.log(
|
86
|
+
LogLevelEnum::DEBUG,
|
87
|
+
format(
|
88
|
+
LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_GOAL,
|
89
|
+
file: FileNameEnum::ImpressionUtil,
|
90
|
+
properties: JSON.generate(impression)
|
91
|
+
)
|
92
|
+
)
|
93
|
+
end
|
94
|
+
impression
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright 2019 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# frozen_string_literal: true
|
16
|
+
|
17
|
+
require 'net/http'
|
18
|
+
|
19
|
+
class VWO
|
20
|
+
module Utils
|
21
|
+
class Request
|
22
|
+
def self.get(url, params)
|
23
|
+
uri = URI.parse(url)
|
24
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
25
|
+
http.use_ssl = true
|
26
|
+
uri.query = URI.encode_www_form(params)
|
27
|
+
Net::HTTP.get_response(uri)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Copyright 2019 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# frozen_string_literal: true
|
16
|
+
|
17
|
+
require 'digest'
|
18
|
+
require_relative '../logger'
|
19
|
+
require_relative '../enums'
|
20
|
+
require_relative '../constants'
|
21
|
+
|
22
|
+
# Utility module for generating uuid
|
23
|
+
class VWO
|
24
|
+
module Utils
|
25
|
+
module UUID
|
26
|
+
include VWO::Enums
|
27
|
+
include VWO::CONSTANTS
|
28
|
+
|
29
|
+
def self.parse(obj)
|
30
|
+
str = obj.to_s.sub(/\Aurn:uuid:/, '')
|
31
|
+
str.gsub!(/[^0-9A-Fa-f]/, '')
|
32
|
+
[str[0..31]].pack 'H*'
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.uuid_v5(uuid_namespace, name)
|
36
|
+
uuid_namespace = parse(uuid_namespace)
|
37
|
+
hash_class = ::Digest::SHA1
|
38
|
+
version = 5
|
39
|
+
|
40
|
+
hash = hash_class.new
|
41
|
+
hash.update(uuid_namespace)
|
42
|
+
hash.update(name)
|
43
|
+
|
44
|
+
ary = hash.digest.unpack('NnnnnN')
|
45
|
+
ary[2] = (ary[2] & 0x0FFF) | (version << 12)
|
46
|
+
ary[3] = (ary[3] & 0x3FFF) | 0x8000
|
47
|
+
# rubocop:disable Lint/FormatString
|
48
|
+
'%08x-%04x-%04x-%04x-%04x%08x' % ary
|
49
|
+
# rubocop:enable Lint/FormatString
|
50
|
+
end
|
51
|
+
|
52
|
+
VWO_NAMESPACE = uuid_v5(URL_NAMESPACE, 'https://vwo.com')
|
53
|
+
|
54
|
+
# Generates desired UUID
|
55
|
+
#
|
56
|
+
# @param[Integer|String] :user_id User identifier
|
57
|
+
# @param[Integer|String] :account_id Account identifier
|
58
|
+
#
|
59
|
+
# @return[Integer] Desired UUID
|
60
|
+
#
|
61
|
+
def generator_for(user_id, account_id)
|
62
|
+
user_id = user_id.to_s
|
63
|
+
account_id = account_id.to_s
|
64
|
+
user_id_namespace = generate(VWO_NAMESPACE, account_id)
|
65
|
+
uuid_for_account_user_id = generate(user_id_namespace, user_id)
|
66
|
+
|
67
|
+
desired_uuid = uuid_for_account_user_id.delete('-').upcase
|
68
|
+
|
69
|
+
VWO::Logger.get_instance.log(
|
70
|
+
LogLevelEnum::DEBUG,
|
71
|
+
format(
|
72
|
+
LogMessageEnum::DebugMessages::UUID_FOR_USER,
|
73
|
+
file: FileNameEnum::UuidUtil,
|
74
|
+
user_id: user_id,
|
75
|
+
account_id: account_id,
|
76
|
+
desired_uuid: desired_uuid
|
77
|
+
)
|
78
|
+
)
|
79
|
+
desired_uuid
|
80
|
+
end
|
81
|
+
|
82
|
+
# Generated uuid from namespace and name, uses uuid5
|
83
|
+
#
|
84
|
+
# @param[String] :namespace Namespace
|
85
|
+
# @param[String) :name Name
|
86
|
+
#
|
87
|
+
# @return[String|nil] UUID, nil if any of the arguments is empty
|
88
|
+
def generate(namespace, name)
|
89
|
+
VWO::Utils::UUID.uuid_v5(namespace, name) if name && namespace
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Copyright 2019 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# frozen_string_literal: true
|
16
|
+
|
17
|
+
require 'json'
|
18
|
+
require 'json-schema'
|
19
|
+
require_relative '../schemas/settings_file'
|
20
|
+
|
21
|
+
class VWO
|
22
|
+
module Utils
|
23
|
+
module Validations
|
24
|
+
# Validates the settings_file
|
25
|
+
# @param [Hash]: JSON object received from VWO server
|
26
|
+
# must be JSON.
|
27
|
+
# @return [Boolean]
|
28
|
+
def valid_settings_file?(settings_file)
|
29
|
+
settings_file = JSON.parse(settings_file)
|
30
|
+
JSON::Validator.validate!(VWO::Schema::SETTINGS_FILE_SCHEMA, settings_file)
|
31
|
+
rescue StandardError
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Boolean]
|
36
|
+
def valid_value?(val)
|
37
|
+
!val.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Boolean]
|
41
|
+
def valid_number?(val)
|
42
|
+
val.is_a?(Numeric)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [Boolean]
|
46
|
+
def valid_string?(val)
|
47
|
+
val.is_a?(String)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Boolean]
|
51
|
+
def valid_hash?(val)
|
52
|
+
val.is_a?(Hash)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vwo-sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- VWO
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: coveralls
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.8.23
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.8.23
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.70'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.70'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: json-schema
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.8'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: murmurhash3
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.1'
|
69
|
+
description: A Ruby SDK for VWO full-stack testing.
|
70
|
+
email:
|
71
|
+
- dev@wingify.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/vwo.rb
|
77
|
+
- lib/vwo/constants.rb
|
78
|
+
- lib/vwo/core/bucketer.rb
|
79
|
+
- lib/vwo/core/variation_decider.rb
|
80
|
+
- lib/vwo/enums.rb
|
81
|
+
- lib/vwo/logger.rb
|
82
|
+
- lib/vwo/schemas/settings_file.rb
|
83
|
+
- lib/vwo/services/event_dispatcher.rb
|
84
|
+
- lib/vwo/services/settings_file_manager.rb
|
85
|
+
- lib/vwo/services/settings_file_processor.rb
|
86
|
+
- lib/vwo/user_storage.rb
|
87
|
+
- lib/vwo/utils/campaign.rb
|
88
|
+
- lib/vwo/utils/function.rb
|
89
|
+
- lib/vwo/utils/impression.rb
|
90
|
+
- lib/vwo/utils/request.rb
|
91
|
+
- lib/vwo/utils/uuid.rb
|
92
|
+
- lib/vwo/utils/validations.rb
|
93
|
+
homepage: https://vwo.com/fullstack/server-side-testing/
|
94
|
+
licenses:
|
95
|
+
- Apache 2.0
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.5.2.3
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Ruby SDK for VWO full-stack testing
|
117
|
+
test_files: []
|