optimizely_server_side 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cbfcb5b065792ea1a3c0456c06e0e8a359112183
4
- data.tar.gz: 3c4d90847f82c04dfb11d65066e2dd510d78477c
3
+ metadata.gz: 6398f138ed81929b7eb9057466e0bb501f21cae3
4
+ data.tar.gz: abc2f4c80d0fa6dc094ed80dfc1395eb66e4685d
5
5
  SHA512:
6
- metadata.gz: 2140ea7013e63bf29a69253a9b68ee492ea080d0660d393c94923f17dd3a056dee25195fc7faf1c811f3d154760638707e6cf00e341ffeb4dfa1a5b99f809749
7
- data.tar.gz: eaeece1f2eeac78be2c9a559a83e0ff6802fe165341e806e8cf41c57f8be4f3bb8c390d1da5028996a827850ae114d07d5ebdd764f346fcd0ad095c0ab9fbe31
6
+ metadata.gz: 6591c7c1872081c2748074891cb9c1f4084fae529a752d2c78ae239b78790709b9fab4bd1ded08d1195116ffffcedc5fc452d68409620b6e9a98afc595a683b8
7
+ data.tar.gz: 75dd78eac9285bfd4bd988552e9fae740572af4916981ee0308e5e39abd6fcbed84b929ec355d0c752a2ca6a3ca7329b8966cc5abba42e0597899a293f118c02
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
4
+ - 2.3.0
5
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,67 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ optimizely_server_side (0.0.1)
5
+ activesupport (~> 4.2, >= 4.2.6)
6
+ optimizely-sdk (~> 0.1.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (4.2.7)
12
+ i18n (~> 0.7)
13
+ json (~> 1.7, >= 1.7.7)
14
+ minitest (~> 5.1)
15
+ thread_safe (~> 0.3, >= 0.3.4)
16
+ tzinfo (~> 1.1)
17
+ addressable (2.3.8)
18
+ crack (0.4.3)
19
+ safe_yaml (~> 1.0.0)
20
+ diff-lcs (1.2.5)
21
+ hashdiff (0.3.0)
22
+ httparty (0.13.7)
23
+ json (~> 1.8)
24
+ multi_xml (>= 0.5.2)
25
+ i18n (0.7.0)
26
+ json (1.8.3)
27
+ json-schema (2.6.2)
28
+ addressable (~> 2.3.8)
29
+ minitest (5.9.0)
30
+ multi_xml (0.5.5)
31
+ murmurhash3 (0.1.6)
32
+ optimizely-sdk (0.1.1)
33
+ httparty (~> 0.13.7)
34
+ json-schema (~> 2.6.2)
35
+ murmurhash3 (~> 0.1.6)
36
+ rspec (3.5.0)
37
+ rspec-core (~> 3.5.0)
38
+ rspec-expectations (~> 3.5.0)
39
+ rspec-mocks (~> 3.5.0)
40
+ rspec-core (3.5.2)
41
+ rspec-support (~> 3.5.0)
42
+ rspec-expectations (3.5.0)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.5.0)
45
+ rspec-mocks (3.5.0)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.5.0)
48
+ rspec-support (3.5.0)
49
+ safe_yaml (1.0.4)
50
+ thread_safe (0.3.5)
51
+ tzinfo (1.2.2)
52
+ thread_safe (~> 0.1)
53
+ webmock (2.1.0)
54
+ addressable (>= 2.3.6)
55
+ crack (>= 0.3.2)
56
+ hashdiff
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ optimizely_server_side!
63
+ rspec (~> 3.5)
64
+ webmock (~> 2.1)
65
+
66
+ BUNDLED WITH
67
+ 1.12.5
data/Readme.md ADDED
@@ -0,0 +1,104 @@
1
+ ## Optimizely Server Side
2
+
3
+ [![Code Climate](https://codeclimate.com/github/ankit8898/optimizely_config_provider/badges/gpa.svg)](https://codeclimate.com/github/ankit8898/optimizely_config_provider) [![Build Status](https://travis-ci.org/ankit8898/optimizely_server_side.svg?branch=master)](https://travis-ci.org/ankit8898/optimizely_server_side)
4
+
5
+ ### What is Optimizely Server Side ?
6
+
7
+ This is a wrapper on top of [Optimizely's](https://app.optimizely.com/projects) ruby sdk called [optimizely-sdk](https://github.com/optimizely/ruby-sdk) . The sdk specializes in server side setup of A/B test . You can read more about it [here](http://developers.optimizely.com/server/introduction/index.html) .
8
+
9
+ ### If we have original sdk why need this wrapper ?
10
+
11
+ This gem solves few things:
12
+
13
+ - **Syncing AB test config across different servers when you don't want to fetch config via REST endpoint or redis/memcache store**
14
+
15
+ If you are using Optimizely you will be aware about the [datafile](http://developers.optimizely.com/server/reference/index.html#datafile). Once we make changes to the A/B test like change in percent distribution, start / pause a experiment this file get's updated.
16
+
17
+ If you have 50 servers with 40 passenger / puma process these process needs to be updated. The Gem polls the config at regular interval and keeps the file cached across different process.
18
+
19
+ The config is stored in **Memory Store** .
20
+
21
+ * **Some additional helpers**
22
+
23
+ Some more helpers exposed that can be exposed in views (.erbs) or PORO's. It avoids duplication of few activation settings.
24
+
25
+ ### Getting Started
26
+
27
+ Add the gem in you Gemfile
28
+
29
+ ```ruby
30
+ gem 'optimizely_server_side'
31
+ ```
32
+
33
+ and
34
+
35
+ ```ruby
36
+ bundle install
37
+ ```
38
+
39
+ Add an initializer in `config/initializers/optimizely_server_side.rb`
40
+
41
+ ```ruby
42
+ #config/initializers/optimizely_server_side.rb
43
+ OptimizelyServerSide.configure do |config|
44
+ config.config_endpoint = 'https://cdn.optimizely.com/json/PROJECT_ID.json'
45
+ config.cache_expiry = 15 #(this is in minutes)
46
+ end
47
+
48
+ ```
49
+ `PROJECT_ID` is a id of your server side project at https://app.optimizely.com .
50
+
51
+
52
+ Optimizely needs a visitor_id to track the unique user and server a constant experience.
53
+
54
+ In your Application controller
55
+
56
+ ```ruby
57
+ class ApplicationController < ActionController::Base
58
+ include OptimizelyServerSide::Support
59
+
60
+ before_action :set_visitor_id
61
+
62
+ def set_visitor_id
63
+ cookies.permanent[:visitor_id] = '1234567' #some visitor_id
64
+
65
+ # This links the browser cookie for visitor_id to
66
+ # OptimizelyServerSide
67
+ OptimizelyServerSide.configure do |config|
68
+ config.visitor_id = cookies[:visitor_id]
69
+ end
70
+ end
71
+
72
+ ```
73
+
74
+
75
+ Now in your views or models
76
+
77
+
78
+ ```ruby
79
+ experiment(EXPERIMENT_KEY) do |config|
80
+
81
+ config.variation_one(VARIATION_ONE_KEY) do
82
+ # Code for experience one. it can be html or a ruby code
83
+ end
84
+
85
+ config.variation_two(VARIATION_TWO_KEY) do
86
+ # Code for experience two. it can be html or a ruby code
87
+ end
88
+
89
+ config.variation_default(VARIATION_DEFAULT_KEY) do
90
+ # Code for experience default. it can be html or a ruby code
91
+ end
92
+
93
+ end
94
+ ```
95
+
96
+ EXPERIMENT_KEY: The experiment key that you will be getting while setting up your experiment from https://app.optimizely.com.
97
+
98
+ VARIATION_ONE_KEY: Key for Variation one. This will be also set when setting up experiment
99
+
100
+ VARIATION_TWO_KEY: Key for Variation two. This will be also set when setting up experiment
101
+
102
+ VARIATION_DEFAULT_KEY: Key for default experience. This will be also set when setting up experiment
103
+
104
+ ![alt text](https://github.com/ankit8898/optimizely_server_side/blob/master/docs/screenshot.png "Logo Title Text 1")
Binary file
@@ -0,0 +1,28 @@
1
+ module OptimizelyServerSide
2
+
3
+ # Maintains the API config response in Memory store cache.
4
+ # user Activesupport MemoryStore store.
5
+ class Cache
6
+
7
+ include Singleton
8
+
9
+ attr_reader :cache_store_instance
10
+
11
+ # We are sticking with Activesupprt memory store as gem is to be used with
12
+ # Rails app for now.
13
+ def initialize
14
+ @cache_store_instance = ActiveSupport::Cache::MemoryStore.new(expires_in: OptimizelyServerSide.configuration.cache_expiry.send(:minutes))
15
+ end
16
+
17
+ class << self
18
+
19
+ # fetch is a wrapper on top of Activesupport Fetch to set/get the
20
+ # response via singleton instance
21
+ def fetch(key)
22
+ instance.cache_store_instance.fetch(key) { yield }
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,16 @@
1
+ module OptimizelyServerSide
2
+
3
+ class Configuration
4
+
5
+ # Configuration enables to open up the configuration of gem for the application.
6
+ # config_endpoint: Optimizely config endpoint
7
+ # cache_expiry: (In minutes) How long we want to cache the config.
8
+ attr_accessor :config_endpoint, :cache_expiry, :visitor_id
9
+
10
+ def initialize
11
+ @config_endpoint = 'http://foo.com'
12
+ @cache_expiry = 15
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module OptimizelyServerSide
2
+
3
+ class DatafileFetcher
4
+ # Responsible for fetching the optimizely sdk config from
5
+ # the API source. The API can be optimizely cdn itself or
6
+ # any other source.
7
+
8
+ class << self
9
+
10
+ # Fetch the Config from the specified source.
11
+ def fetch
12
+ Net::HTTP.get(URI(OptimizelyServerSide.configuration.config_endpoint))
13
+ end
14
+ alias_method :datafile, :fetch
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ module OptimizelyServerSide
2
+
3
+ module Support
4
+
5
+ # Enables for us to wrap experiments
6
+ # Usage:
7
+ # experiment('sign_up_test') do |config|
8
+ #
9
+ # config.variation_one('variation_one_key') do
10
+ # # Code related to variation one
11
+ # end
12
+ #
13
+ # config.variation_two('variation_two_key') do
14
+ # # Code related to variation two
15
+ # end
16
+ #
17
+ # config.variation_default('variation_default_key') do
18
+ # # We still want to keep our default experience
19
+ # end
20
+ #
21
+ # end
22
+
23
+ def experiment(experiment_key, &blk)
24
+ result_variation_key = optimizely_sdk_project_instance(experiment_key)
25
+ variation_instance = OptimizelyServerSide::Variation.new(result_variation_key)
26
+ blk.call(variation_instance)
27
+ variation_instance.compute
28
+ end
29
+
30
+ def optimizely_sdk_project_instance(experiment_key)
31
+ OptimizelyServerSide::OptimizelySdk.project_instance(event_dispather: MyEventDispatcher.new).activate(experiment_key, OptimizelyServerSide.configuration.visitor_id)
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ module OptimizelyServerSide
2
+
3
+ class OptimizelySdk
4
+
5
+ # Public method to be accessed in the application
6
+ # This is the project instance and is giving
7
+ # access to all the optimizely sdk methods.
8
+ # Datafile
9
+ def self.project_instance(options = {})
10
+ Cache.fetch('optimizely_sdk_config'.freeze) do
11
+ puts "Getting the configg"
12
+ Optimizely::Project.new(DatafileFetcher.datafile, options[:event_dispather])
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,38 @@
1
+ module OptimizelyServerSide
2
+
3
+ class Variation
4
+
5
+ attr_reader :hsh
6
+
7
+ def initialize(variation_key)
8
+ @variation_key = variation_key
9
+ @hsh = {}
10
+ end
11
+
12
+ # Variation one of experiment
13
+ def variation_one(key)
14
+ @hsh[key] = yield
15
+ end
16
+
17
+ # Variation two of experiment
18
+ def variation_two(key)
19
+ @hsh[key] = yield
20
+ end
21
+
22
+ def variation_default(key)
23
+ @hsh[key] = yield
24
+ end
25
+
26
+ # Variation three of experiment
27
+ def variation_three(key)
28
+ @hsh[key] = yield
29
+ end
30
+
31
+ # Select which variation to be picked up
32
+ def compute
33
+ @hsh.select do |key,value|
34
+ key == @variation_key
35
+ end.values[0]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'optimizely_server_side'
5
+ s.version = '0.0.3'
6
+ s.date = '2016-08-10'
7
+ s.summary = "Optimizely server side. A wrapper on top of optimizely's ruby sdk for easy caching of server side config "
8
+ s.description = "Optimizely server side. A wrapper on top of optimizely's ruby sdk for easy caching of server side config and exposing few more utility helpers "
9
+ s.authors = ["Ankit Gupta"]
10
+ s.email = 'ankit.gupta8898@gmail.com'
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
+
14
+ s.require_paths = ["lib"]
15
+ s.homepage =
16
+ 'https://github.com/ankit8898/optimizely_server_side'
17
+ s.license = 'MIT'
18
+ s.add_development_dependency 'rspec', '~> 3.5'
19
+ s.add_development_dependency 'webmock', '~> 2.1'
20
+ s.add_runtime_dependency 'optimizely-sdk' , '~> 0.1.1'
21
+ s.add_runtime_dependency 'activesupport', '~> 4.2', '>= 4.2.6'
22
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OptimizelyServerSide::Cache do
4
+
5
+ describe 'singleton' do
6
+
7
+ it 'should be a singleton instance' do
8
+ expect(described_class.instance).to equal(described_class.instance)
9
+ end
10
+ end
11
+
12
+
13
+ describe '#cache_store_instance' do
14
+
15
+ it 'should be a instance of Activesupport memory store' do
16
+ expect(described_class.instance.cache_store_instance).to be_kind_of(ActiveSupport::Cache::MemoryStore)
17
+ end
18
+
19
+ end
20
+
21
+ describe '.fetch' do
22
+
23
+ before do
24
+ stub_request(:get, "https://cdn.optimizely.com/json/5960232316.json")
25
+ .to_return(body: '{"experiments": [{"status": "running"}]}',status: 200)
26
+ end
27
+
28
+ it 'should return the config from API and cache it' do
29
+ expect(
30
+ described_class.fetch('key') do
31
+ JSON.parse(OptimizelyServerSide::DatafileFetcher.datafile, symbolize_names: true)
32
+ end
33
+ ).to eq(
34
+ {
35
+ experiments: [{status: "running"}]
36
+ }
37
+ )
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OptimizelyServerSide::Configuration do
4
+
5
+ subject { OptimizelyServerSide::Configuration.new }
6
+
7
+ describe '#config_endpoint' do
8
+
9
+ it 'has a default value of http://foo.com' do
10
+ expect(subject.config_endpoint).to eq('http://foo.com')
11
+ end
12
+
13
+ end
14
+
15
+ describe '#visitor_id' do
16
+
17
+ it 'defaults to nil' do
18
+ expect(subject.visitor_id).to be_nil
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OptimizelyServerSide::DatafileFetcher do
4
+
5
+ describe '#fetch' do
6
+
7
+ before do
8
+ stub_request(:get, "https://cdn.optimizely.com/json/5960232316.json")
9
+ .to_return(body: '{"experiments": [{"status": "running"}]}',status: 200)
10
+ end
11
+
12
+ it 'should fetch the config' do
13
+ expect(described_class.fetch).to eq('{"experiments": [{"status": "running"}]}')
14
+ end
15
+
16
+
17
+ it 'should return stringified datafile' do
18
+ expect(described_class.datafile).to eq('{"experiments": [{"status": "running"}]}')
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OptimizelyServerSide::Support do
4
+
5
+ class FakeKlass
6
+
7
+ include OptimizelyServerSide::Support
8
+
9
+
10
+ def some_klass_method
11
+
12
+ experiment('foo_experiment_key') do |config|
13
+
14
+ config.variation_one('variation_one') do
15
+ 'Experience one'
16
+ end
17
+
18
+ config.variation_two('variation_two') do
19
+ 'Experience two'
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ context '#experiment' do
28
+
29
+ subject { FakeKlass.new }
30
+
31
+ before do
32
+ allow(subject).to receive(:optimizely_sdk_project_instance).and_return('variation_one')
33
+ end
34
+
35
+ it { expect(subject.some_klass_method).to eq('Experience one')}
36
+ end
37
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OptimizelyServerSide::OptimizelySdk do
4
+
5
+ let(:valid_datafile) do
6
+ '{
7
+ "experiments": [{
8
+ "status": "Paused",
9
+ "percentageIncluded": 10000,
10
+ "key": "PROPERTY_HISTORY_TEST",
11
+ "trafficAllocation": [{
12
+ "entityId": "6038700472",
13
+ "endOfRange": 2500
14
+ }, {
15
+ "entityId": "6038700473",
16
+ "endOfRange": 7500
17
+ }, {
18
+ "entityId": "6038700474",
19
+ "endOfRange": 10000
20
+ }],
21
+ "audienceIds": [],
22
+ "variations": [{
23
+ "id": "6038700472",
24
+ "key": "PROPERTY_HISTORY_IMAGE_ONE"
25
+ }, {
26
+ "id": "6038700473",
27
+ "key": "PROPERTY_HISTORY_IMAGE_TWO"
28
+ }, {
29
+ "id": "6038700474",
30
+ "key": "DEFAULT"
31
+ }],
32
+ "forcedVariations": {},
33
+ "id": "6051271599"
34
+ }, {
35
+ "status": "Archived",
36
+ "percentageIncluded": 10000,
37
+ "key": "FS_SRP_MapPlusListView",
38
+ "trafficAllocation": [{
39
+ "entityId": "6236690179",
40
+ "endOfRange": 10000
41
+ }],
42
+ "audienceIds": [],
43
+ "variations": [{
44
+ "id": "6236690179",
45
+ "key": "MapViewPlusList"
46
+ }],
47
+ "forcedVariations": {},
48
+ "id": "6240360321"
49
+ }, {
50
+ "status": "Running",
51
+ "percentageIncluded": 10000,
52
+ "key": "MAPVERTISING",
53
+ "trafficAllocation": [{
54
+ "entityId": "6832840236",
55
+ "endOfRange": 3000
56
+ }, {
57
+ "entityId": "6832840237",
58
+ "endOfRange": 10000
59
+ }],
60
+ "audienceIds": [],
61
+ "variations": [{
62
+ "id": "6832840236",
63
+ "key": "VERSION_A"
64
+ }, {
65
+ "id": "6832840237",
66
+ "key": "VERSION_B"
67
+ }],
68
+ "forcedVariations": {},
69
+ "id": "6839510990"
70
+ }],
71
+ "version": "1",
72
+ "audiences": [],
73
+ "dimensions": [{
74
+ "id": "6202664479",
75
+ "key": "geography",
76
+ "segmentId": "6236461184"
77
+ }],
78
+ "groups": [],
79
+ "projectId": "5960232316",
80
+ "accountId": "5955320306",
81
+ "events": [{
82
+ "experimentIds": ["6051271599"],
83
+ "id": "6048790108",
84
+ "key": "Property history image check goal"
85
+ }, {
86
+ "experimentIds": ["6240360321"],
87
+ "id": "6231170981",
88
+ "key": "MapTest"
89
+ }, {
90
+ "experimentIds": ["6839510990"],
91
+ "id": "6813060279",
92
+ "key": "MAPVERTISING_GOAL"
93
+ }, {
94
+ "experimentIds": [],
95
+ "id": "5927811380",
96
+ "key": "Total Revenue"
97
+ }],
98
+ "revision": "23"
99
+ }'
100
+ end
101
+
102
+ describe '.project_instance' do
103
+
104
+ before do
105
+ stub_request(:get, "https://cdn.optimizely.com/json/5960232316.json")
106
+ .to_return(body: valid_datafile, status: 200)
107
+ end
108
+
109
+ it 'returns an OptimizelySdk project instance' do
110
+ expect(described_class.project_instance).to be_kind_of(Optimizely::Project)
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,137 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OptimizelyServerSide::Variation do
4
+
5
+ subject { OptimizelyServerSide::Variation.new(variation_key = 'variation_key_a') }
6
+
7
+
8
+ describe '#compute' do
9
+
10
+
11
+ before do
12
+
13
+ subject.variation_one('variation_key_a') do
14
+ 'experience a'
15
+ end
16
+
17
+ subject.variation_two('variation_key_b') do
18
+ 'experience b'
19
+ end
20
+
21
+ end
22
+
23
+ it 'should result variation b' do
24
+ expect(subject.compute).to eq('experience a')
25
+ end
26
+ end
27
+
28
+
29
+ ['variation_one','variation_two','variation_three','variation_default'].each do |variation|
30
+
31
+ describe "#{variation}" do
32
+
33
+ context 'it accepts regular strings' do
34
+
35
+ it do
36
+ expect(subject.send(variation,'foo') do
37
+ 'Hello!'
38
+ end).to eq('Hello!')
39
+ end
40
+
41
+ end
42
+
43
+
44
+ context 'it accepts a block' do
45
+
46
+ let(:some_block) do
47
+ -> { 'something'}
48
+ end
49
+
50
+ it do
51
+ expect(subject.send(variation,'foo') do
52
+ some_block
53
+ end).to eq(some_block)
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+
61
+ describe '#hsh' do
62
+
63
+ context 'key accepts regular strings' do
64
+
65
+ let(:string) { 'I am a variation' }
66
+
67
+ before do
68
+ subject.variation_one('foo') do
69
+ string
70
+ end
71
+ end
72
+
73
+ it 'has value as string' do
74
+ expect(subject.hsh).to eq({'foo' => string})
75
+ end
76
+
77
+ end
78
+
79
+
80
+ context 'key accepts blocks / proc' do
81
+
82
+ let(:proc) { Proc.new {|n| n*2 } }
83
+
84
+ before do
85
+ subject.variation_one('foo') do
86
+ proc
87
+ end
88
+ end
89
+
90
+ it 'has value as proc' do
91
+ expect(subject.hsh).to eq({'foo' => proc})
92
+ end
93
+
94
+ end
95
+
96
+ context 'key accepts string, html or blocks / proc' do
97
+
98
+ let(:proc) { Proc.new {|n| n*2 } }
99
+ let(:html) do
100
+ '<!DOCTYPE html>
101
+ <html>
102
+ <head>
103
+ <title>Page Title</title>
104
+ </head>
105
+ <body>
106
+
107
+ <h1>This is a Heading</h1>
108
+ <p>This is a paragraph.</p>
109
+
110
+ </body>
111
+ </html>
112
+ '
113
+ end
114
+ let(:string) { 'Hello!'}
115
+
116
+ before do
117
+ subject.variation_one('foo') do
118
+ proc
119
+ end
120
+
121
+ subject.variation_two('foo_two') do
122
+ html
123
+ end
124
+
125
+ subject.variation_three('foo_three') do
126
+ string
127
+ end
128
+ end
129
+
130
+ it 'has value as proc' do
131
+ expect(subject.hsh).to eq({'foo' => proc, 'foo_two' => html, 'foo_three' => string})
132
+ end
133
+
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OptimizelyServerSide do
4
+
5
+ describe "#configure" do
6
+
7
+ context 'when config is set in regular way' do
8
+
9
+ before do
10
+ OptimizelyServerSide.configure do |config|
11
+ config.config_endpoint = 'https://cdn.optimizely.com/json/5960232316.json'
12
+ config.cache_expiry = 12
13
+ end
14
+ end
15
+
16
+ it 'has config_endpoint' do
17
+ expect(OptimizelyServerSide.configuration.config_endpoint).to eq('https://cdn.optimizely.com/json/5960232316.json')
18
+ end
19
+
20
+ it 'has cache_expiry' do
21
+ expect(OptimizelyServerSide.configuration.cache_expiry).to eq(12)
22
+ end
23
+
24
+ it 'has no visitor_id' do
25
+ expect(OptimizelyServerSide.configuration.visitor_id).to be_nil
26
+ end
27
+ end
28
+
29
+
30
+ context 'when config is set in between' do
31
+
32
+ before do
33
+ OptimizelyServerSide.configure do |config|
34
+ config.config_endpoint = 'https://cdn.optimizely.com/json/5960232316.json'
35
+ config.cache_expiry = 12
36
+ end
37
+ end
38
+
39
+ it 'has config_endpoint' do
40
+ OptimizelyServerSide.configure do |config|
41
+ config.visitor_id = '1234abcdef'
42
+ end
43
+
44
+ expect(OptimizelyServerSide.configuration.config_endpoint).to eq('https://cdn.optimizely.com/json/5960232316.json')
45
+ end
46
+
47
+ it 'has cache_expiry' do
48
+ expect(OptimizelyServerSide.configuration.cache_expiry).to eq(12)
49
+ end
50
+
51
+ it 'has no visitor_id' do
52
+ expect(OptimizelyServerSide.configuration.visitor_id).to eq('1234abcdef')
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+
59
+ def foo
60
+ experiment(EXPERIMENT_KEY) do |config|
61
+
62
+ config.variation_one(VARIATION_ONE_KEY) do
63
+ # Code for experience one. it can be html or a ruby code
64
+ end
65
+
66
+ config.variation_two(VARIATION_TWO_KEY) do
67
+ # Code for experience two. it can be html or a ruby code
68
+ end
69
+
70
+ config.variation_default(variation_default_KEY) do
71
+ # Code for experience default. it can be html or a ruby code
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,15 @@
1
+ require 'bundler/setup'
2
+ require 'webmock/rspec'
3
+ Bundler.setup
4
+
5
+ require 'optimizely_server_side'
6
+
7
+ RSpec.configure do |config|
8
+ # some (optional) config here
9
+
10
+ config.before do
11
+ OptimizelyServerSide.configure do |config|
12
+ config.config_endpoint = 'https://cdn.optimizely.com/json/5960232316.json'
13
+ end
14
+ end
15
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optimizely_server_side
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ankit Gupta
@@ -79,7 +79,29 @@ executables: []
79
79
  extensions: []
80
80
  extra_rdoc_files: []
81
81
  files:
82
+ - ".gitignore"
83
+ - ".rspec"
84
+ - ".travis.yml"
85
+ - Gemfile
86
+ - Gemfile.lock
87
+ - Readme.md
88
+ - docs/screenshot.png
82
89
  - lib/optimizely_server_side.rb
90
+ - lib/optimizely_server_side/cache.rb
91
+ - lib/optimizely_server_side/configuration.rb
92
+ - lib/optimizely_server_side/datafile_fetcher.rb
93
+ - lib/optimizely_server_side/helpers/support.rb
94
+ - lib/optimizely_server_side/optimizely_sdk.rb
95
+ - lib/optimizely_server_side/variation.rb
96
+ - optimizely_server_side.gemspec
97
+ - spec/optimizely_server_side/cache_spec.rb
98
+ - spec/optimizely_server_side/configuration_spec.rb
99
+ - spec/optimizely_server_side/datafile_fetcher_spec.rb
100
+ - spec/optimizely_server_side/helpers/support_spec.rb
101
+ - spec/optimizely_server_side/optimizely_sdk_spec.rb
102
+ - spec/optimizely_server_side/variation_spec.rb
103
+ - spec/optimizely_server_side_spec.rb
104
+ - spec/spec_helper.rb
83
105
  homepage: https://github.com/ankit8898/optimizely_server_side
84
106
  licenses:
85
107
  - MIT
@@ -105,4 +127,12 @@ signing_key:
105
127
  specification_version: 4
106
128
  summary: Optimizely server side. A wrapper on top of optimizely's ruby sdk for easy
107
129
  caching of server side config
108
- test_files: []
130
+ test_files:
131
+ - spec/optimizely_server_side/cache_spec.rb
132
+ - spec/optimizely_server_side/configuration_spec.rb
133
+ - spec/optimizely_server_side/datafile_fetcher_spec.rb
134
+ - spec/optimizely_server_side/helpers/support_spec.rb
135
+ - spec/optimizely_server_side/optimizely_sdk_spec.rb
136
+ - spec/optimizely_server_side/variation_spec.rb
137
+ - spec/optimizely_server_side_spec.rb
138
+ - spec/spec_helper.rb