Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 12:55:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 12:55:51 +0300
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /spec/experiments
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/experiments')
-rw-r--r--spec/experiments/application_experiment_spec.rb164
-rw-r--r--spec/experiments/new_project_readme_content_experiment_spec.rb36
2 files changed, 127 insertions, 73 deletions
diff --git a/spec/experiments/application_experiment_spec.rb b/spec/experiments/application_experiment_spec.rb
index 22c436e4159..9c03910cf66 100644
--- a/spec/experiments/application_experiment_spec.rb
+++ b/spec/experiments/application_experiment_spec.rb
@@ -3,11 +3,10 @@
require 'spec_helper'
RSpec.describe ApplicationExperiment, :experiment do
- subject { described_class.new('namespaced/stub') }
+ subject { described_class.new('namespaced/stub', **context) }
- let(:feature_definition) do
- { name: 'namespaced_stub', type: 'experiment', group: 'group::adoption', default_enabled: false }
- end
+ let(:context) { {} }
+ let(:feature_definition) { { name: 'namespaced_stub', type: 'experiment', default_enabled: false } }
around do |example|
Feature::Definition.definitions[:namespaced_stub] = Feature::Definition.new('namespaced_stub.yml', feature_definition)
@@ -19,19 +18,13 @@ RSpec.describe ApplicationExperiment, :experiment do
allow(subject).to receive(:enabled?).and_return(true)
end
- it "naively assumes a 1x1 relationship to feature flags for tests" do
- expect(Feature).to receive(:persist_used!).with('namespaced_stub')
-
- described_class.new('namespaced/stub')
- end
-
it "doesn't raise an exception without a defined control" do
# because we have a default behavior defined
expect { experiment('namespaced/stub') { } }.not_to raise_error
end
- describe "enabled" do
+ describe "#enabled?" do
before do
allow(subject).to receive(:enabled?).and_call_original
@@ -63,103 +56,104 @@ RSpec.describe ApplicationExperiment, :experiment do
end
end
- describe "publishing results" do
- it "doesn't record, track or push data to the client if we shouldn't track", :snowplow do
+ describe "#publish" do
+ it "doesn't track or publish to the client or database if we can't track", :snowplow do
allow(subject).to receive(:should_track?).and_return(false)
- subject.record!
- expect(subject).not_to receive(:record_experiment)
- expect(subject).not_to receive(:track)
- expect(Gon).not_to receive(:push)
+ expect(subject).not_to receive(:publish_to_client)
+ expect(subject).not_to receive(:publish_to_database)
- subject.publish(:action)
+ subject.publish
expect_no_snowplow_event
end
- describe 'recording the experiment' do
- it 'does not record the experiment if we do not tell it to' do
- expect(subject).not_to receive(:record_experiment)
-
- subject.publish
- end
-
- it 'records the experiment if we tell it to' do
- subject.record!
-
- expect(subject).to receive(:record_experiment)
-
- subject.publish
- end
- end
-
it "tracks the assignment" do
expect(subject).to receive(:track).with(:assignment)
subject.publish
end
- it "pushes the experiment knowledge into the client using Gon" do
- expect(Gon).to receive(:push).with({ experiment: { 'namespaced/stub' => subject.signature } }, true)
+ it "publishes the to the client" do
+ expect(subject).to receive(:publish_to_client)
subject.publish
end
- it "handles when Gon raises exceptions (like when it can't be pushed into)" do
- expect(Gon).to receive(:push).and_raise(NoMethodError)
+ it "publishes to the database if we've opted for that" do
+ subject.record!
+
+ expect(subject).to receive(:publish_to_database)
- expect { subject.publish }.not_to raise_error
+ subject.publish
end
- end
- it "can exclude from within the block" do
- expect(described_class.new('namespaced/stub') { |e| e.exclude! }).to be_excluded
- end
+ describe "#publish_to_client" do
+ it "adds the data into Gon" do
+ signature = { key: '86208ac54ca798e11f127e8b23ec396a', variant: 'control' }
+ expect(Gon).to receive(:push).with({ experiment: { 'namespaced/stub' => hash_including(signature) } }, true)
- describe 'recording the experiment subject' do
- using RSpec::Parameterized::TableSyntax
+ subject.publish_to_client
+ end
- subject { described_class.new('namespaced/stub', nil, **context) }
+ it "handles when Gon raises exceptions (like when it can't be pushed into)" do
+ expect(Gon).to receive(:push).and_raise(NoMethodError)
- before do
- subject.record!
+ expect { subject.publish_to_client }.not_to raise_error
+ end
end
- context 'when providing a compatible context' do
- where(:context_key, :object_type) do
- :namespace | :namespace
- :group | :namespace
- :project | :project
- :user | :user
- :actor | :user
+ describe "#publish_to_database" do
+ using RSpec::Parameterized::TableSyntax
+ let(:context) { { context_key => context_value }}
+
+ before do
+ subject.record!
end
- with_them do
- let(:context) { { context_key => build(object_type) }}
+ context "when there's a usable subject" do
+ where(:context_key, :context_value, :object_type) do
+ :namespace | build(:namespace) | :namespace
+ :group | build(:namespace) | :namespace
+ :project | build(:project) | :project
+ :user | build(:user) | :user
+ :actor | build(:user) | :user
+ end
- it 'records the experiment and the experiment subject from the context' do
- expect { subject.publish }.to change(Experiment, :count).by(1)
+ with_them do
+ it "creates an experiment and experiment subject record" do
+ expect { subject.publish_to_database }.to change(Experiment, :count).by(1)
- expect(Experiment.last.name).to eq('namespaced/stub')
- expect(ExperimentSubject.last.send(object_type)).to eq(context[context_key])
+ expect(Experiment.last.name).to eq('namespaced/stub')
+ expect(ExperimentSubject.last.send(object_type)).to eq(context[context_key])
+ end
end
end
- end
- context 'when providing an incompatible or no context' do
- where(context_hash: [{ foo: :bar }, {}])
+ context "when there's not a usable subject" do
+ where(:context_key, :context_value) do
+ :namespace | nil
+ :foo | :bar
+ end
- with_them do
- let(:context) { context_hash }
+ with_them do
+ it "doesn't create an experiment record" do
+ expect { subject.publish_to_database }.not_to change(Experiment, :count)
+ end
- it 'does not record the experiment' do
- expect { subject.publish }.not_to change(Experiment, :count)
+ it "doesn't create an experiment subject record" do
+ expect { subject.publish_to_database }.not_to change(ExperimentSubject, :count)
+ end
end
end
end
end
- describe "tracking events", :snowplow do
+ describe "#track", :snowplow do
+ let(:fake_context) do
+ SnowplowTracker::SelfDescribingJson.new('iglu:com.gitlab/fake/jsonschema/0-0-0', { data: '_data_' })
+ end
+
it "doesn't track if we shouldn't track" do
allow(subject).to receive(:should_track?).and_return(false)
@@ -169,9 +163,7 @@ RSpec.describe ApplicationExperiment, :experiment do
end
it "tracks the event with the expected arguments and merged contexts" do
- subject.track(:action, property: '_property_', context: [
- SnowplowTracker::SelfDescribingJson.new('iglu:com.gitlab/fake/jsonschema/0-0-0', { data: '_data_' })
- ])
+ subject.track(:action, property: '_property_', context: [fake_context])
expect_snowplow_event(
category: 'namespaced/stub',
@@ -189,9 +181,35 @@ RSpec.describe ApplicationExperiment, :experiment do
]
)
end
+
+ it "tracks the event correctly even when using the base class" do
+ subject = Gitlab::Experiment.new(:unnamed)
+ subject.track(:action, context: [fake_context])
+
+ expect_snowplow_event(
+ category: 'unnamed',
+ action: 'action',
+ context: [
+ {
+ schema: 'iglu:com.gitlab/fake/jsonschema/0-0-0',
+ data: { data: '_data_' }
+ },
+ {
+ schema: 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0',
+ data: { experiment: 'unnamed', key: subject.context.key, variant: 'control' }
+ }
+ ]
+ )
+ end
+ end
+
+ describe "#key_for" do
+ it "generates MD5 hashes" do
+ expect(subject.key_for(foo: :bar)).to eq('6f9ac12afdb9b58c2f19a136d09f9153')
+ end
end
- describe "variant resolution" do
+ context "when resolving variants" do
it "uses the default value as specified in the yaml" do
expect(Feature).to receive(:enabled?).with('namespaced_stub', subject, type: :experiment, default_enabled: :yaml)
diff --git a/spec/experiments/new_project_readme_content_experiment_spec.rb b/spec/experiments/new_project_readme_content_experiment_spec.rb
new file mode 100644
index 00000000000..92a883078df
--- /dev/null
+++ b/spec/experiments/new_project_readme_content_experiment_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe NewProjectReadmeContentExperiment, :experiment do
+ subject { described_class.new(namespace: project.namespace) }
+
+ let(:project) { create(:project, name: 'Experimental', description: 'An experiment project') }
+
+ it "renders the basic README" do
+ expect(subject.run_with(project)).to eq(<<~MARKDOWN.strip)
+ # Experimental
+
+ An experiment project
+ MARKDOWN
+ end
+
+ describe "the advanced variant" do
+ let(:markdown) { subject.run_with(project, variant: :advanced) }
+ let(:initial_url) { 'https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file' }
+
+ it "renders the project details" do
+ expect(markdown).to include(<<~MARKDOWN.strip)
+ # Experimental
+
+ An experiment project
+
+ ## Getting started
+ MARKDOWN
+ end
+
+ it "renders redirect URLs" do
+ expect(markdown).to include(Rails.application.routes.url_helpers.experiment_redirect_url(subject, initial_url))
+ end
+ end
+end