Skip to content

Commit

Permalink
refactor(examples): structure contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
marian13 committed Jan 14, 2024
1 parent 6a641c8 commit fff27d0
Show file tree
Hide file tree
Showing 11 changed files with 398 additions and 428 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

# rubocop:disable RSpec/NestedGroups, RSpec/MultipleMemoizedHelpers
RSpec.describe ConvenientService::Examples::Standard::RequestParams::Services::Prepare do
include ConvenientService::RSpec::Matchers::DelegateTo
include ConvenientService::RSpec::Matchers::Results

example_group "class methods" do
describe ".result" do
include ConvenientService::RSpec::Matchers::DelegateTo
include ConvenientService::RSpec::Matchers::Results

subject(:result) { described_class.result(request: request) }

let(:request) { ConvenientService::Examples::Standard::RequestParams::Entities::Request.new(http_string: http_string) }
Expand Down Expand Up @@ -49,13 +49,9 @@
end

let(:path) { "/rules/%{id}.%{format}" % path_params }

let(:path_params) { {id: id, format: format} }

let(:id) { "1000000" }

let(:format) { "json" }

let(:body) { JSON.generate(json_body) }

let(:json_body) do
Expand All @@ -69,13 +65,9 @@
end

let(:body_params) { json_body.transform_keys(&:to_sym) }

let(:merged_params) { path_params.merge(body_params) }

let(:permitted_params) { merged_params.slice(*(merged_params.keys - [:verified])) }

let(:params_with_defaults) { defaults.merge(permitted_params) }

let(:original_params) { params_with_defaults }

let(:casted_params) do
Expand All @@ -96,100 +88,84 @@
allow(ConvenientService::Examples::Standard::RequestParams::Entities::Logger).to receive(:log).with(anything)
end

context "when request is NOT valid to extract params from path" do
##
# Contains invalid path.
# https://www.w3.org/TR/2011/WD-html5-20110525/urls.html
#
let(:path) { "/ru*les/1.json" }
let(:pattern) { /^\/rules\/(?<id>\d+)\.(?<format>\w+)$/ }
context "when `Prepare` is NOT successful" do
context "when `ExtractParamsFromPath` is NOT successful" do
##
# Contains invalid path.
# https://www.w3.org/TR/2011/WD-html5-20110525/urls.html
#
let(:path) { "/ru*les/1.json" }
let(:pattern) { /^\/rules\/(?<id>\d+)\.(?<format>\w+)$/ }

it "fails to extract params from path" do
expect(result).to be_error.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ExtractParamsFromPath)
it "returns intermediate step result" do
expect(result).to be_not_success.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ExtractParamsFromPath)
end
end
end

context "when request is NOT valid to extract params from body" do
##
# Contains unparsable JSON body.
#
let(:body) { "abc" }
context "when `ExtractParamsFromBody` is NOT successful" do
##
# Contains unparsable JSON body.
#
let(:body) { "abc" }

it "fails to extract params from body" do
expect(result).to be_error.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ExtractParamsFromBody)
it "returns intermediate step result" do
expect(result).to be_not_success.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ExtractParamsFromBody)
end
end
end

context "when request is valid to extract params from both path and body" do
it "merges params extracted from path and body" do
context "when uncasted params are NOT valid" do
##
# TODO: Introduce `delegate_to_service` to hide `commit_config!`.
# Contains unsupported format, only JSON is available.
#
ConvenientService::Examples::Standard::RequestParams::Services::MergeParams.commit_config!
let(:path) { "/rules/1.html" }

it "returns intermediate step result" do
expect(result).to be_not_success.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ValidateUncastedParams)
end
end

context "when casted params are NOT valid" do
before do
allow(ConvenientService::Examples::Standard::RequestParams::Entities::ID).to receive(:cast).and_return(nil)
end

it "returns intermediate step result" do
expect(result).to be_not_success.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ValidateCastedParams)
end
end
end

context "when `Prepare` is successful" do
specify do
expect { result }
.to delegate_to(ConvenientService::Examples::Standard::RequestParams::Services::MergeParams, :result)
.with_arguments(params_from_path: path_params, params_from_body: body_params)
end

it "logs merged params from path and body with \"Uncasted\" tag" do
##
# TODO: Introduce `delegate_to_service` to hide `commit_config!`.
#
ConvenientService::Examples::Standard::RequestParams::Services::LogRequestParams.commit_config!

specify do
expect { result }
.to delegate_to(ConvenientService::Examples::Standard::RequestParams::Services::LogRequestParams, :result)
.with_arguments(request: request, params: merged_params, tag: "Uncasted")
end

it "filters out unpermitted keys" do
ConvenientService::Examples::Standard::RequestParams::Services::FilterOutUnpermittedParams.commit_config!

specify do
expect { result }
.to delegate_to(ConvenientService::Examples::Standard::RequestParams::Services::FilterOutUnpermittedParams, :result)
.with_arguments(params: merged_params, permitted_keys: permitted_keys)
end

it "applies default values" do
ConvenientService::Examples::Standard::RequestParams::Services::ApplyDefaultParamValues.commit_config!

specify do
expect { result }
.to delegate_to(ConvenientService::Examples::Standard::RequestParams::Services::ApplyDefaultParamValues, :result)
.with_arguments(params: permitted_params, defaults: defaults)
end
end

context "when uncasted params are NOT valid" do
##
# Contains unsupported format, only JSON is available.
#
let(:path) { "/rules/1.html" }

it "fails to validate uncasted params" do
expect(result).to be_error.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ValidateUncastedParams)
end
end

context "when uncasted params are valid" do
it "logs casted params with \"Casted\" tag" do
specify do
expect { result }
.to delegate_to(ConvenientService::Examples::Standard::RequestParams::Services::LogRequestParams, :result)
.with_arguments(request: request, params: casted_params, tag: "Casted")
end
end

context "when casted params are NOT valid" do
before do
allow(ConvenientService::Examples::Standard::RequestParams::Entities::ID).to receive(:cast).and_return(nil)
end

it "fails to validate casted params" do
expect(result).to be_error.of_step(ConvenientService::Examples::Standard::RequestParams::Services::ValidateCastedParams)
end
end

context "when casted params are valid" do
it "returns `success` with casted params" do
expect(result).to be_success.with_data(params: casted_params)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@

# rubocop:disable RSpec/NestedGroups
RSpec.describe ConvenientService::Examples::Standard::V1::RequestParams::Services::ApplyDefaultParamValues do
include ConvenientService::RSpec::Matchers::Results

example_group "class methods" do
describe ".result" do
include ConvenientService::RSpec::Matchers::Results

subject(:result) { described_class.result(params: params, defaults: defaults) }
context "when `ApplyDefaultParamValues` is successful" do
subject(:result) { described_class.result(params: params, defaults: defaults) }

let(:params) { {id: "1000000", title: "Check the official User Docs"} }
let(:defaults) { {tags: [], sources: []} }
let(:params) { {id: "1000000", title: "Check the official User Docs"} }
let(:defaults) { {tags: [], sources: []} }

it "returns success with params and defaults" do
expect(result).to be_success.with_data(params: {id: "1000000", title: "Check the official User Docs", tags: [], sources: []})
end
it "returns `success` with params and defaults" do
expect(result).to be_success.with_data(params: {id: "1000000", title: "Check the official User Docs", tags: [], sources: []})
end

context "when `params` and `defaults` have same keys" do
let(:params) { {id: "1000000", title: "Check the official User Docs", tags: ["ruby"]} }
context "when `params` and `defaults` have same keys" do
let(:params) { {id: "1000000", title: "Check the official User Docs", tags: ["ruby"]} }

it "takes value from `params`" do
expect(result).to be_success.with_data(params: {id: "1000000", title: "Check the official User Docs", tags: ["ruby"], sources: []})
it "takes value from `params`" do
expect(result).to be_success.with_data(params: {id: "1000000", title: "Check the official User Docs", tags: ["ruby"], sources: []})
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,38 @@

# rubocop:disable RSpec/NestedGroups
RSpec.describe ConvenientService::Examples::Standard::V1::RequestParams::Services::CastParams do
include ConvenientService::RSpec::Matchers::Results

example_group "class methods" do
describe ".result" do
include ConvenientService::RSpec::Matchers::Results

subject(:result) { described_class.result(params: original_params) }
context "when `CastParams` is successful" do
subject(:result) { described_class.result(params: original_params) }

let(:original_params) do
{
id: "1000000",
format: "html",
title: "Avoid error shadowing",
description: "Check the official User Docs",
tags: "ruby",
sources: "https://www.rubyguides.com/2019/07/ruby-instance-variables/"
}
end
let(:original_params) do
{
id: "1000000",
format: "html",
title: "Avoid error shadowing",
description: "Check the official User Docs",
tags: "ruby",
sources: "https://www.rubyguides.com/2019/07/ruby-instance-variables/"
}
end

let(:casted_params) do
{
id: ConvenientService::Examples::Standard::V1::RequestParams::Entities::ID.cast(original_params[:id]),
format: ConvenientService::Examples::Standard::V1::RequestParams::Entities::Format.cast(original_params[:format]),
title: ConvenientService::Examples::Standard::V1::RequestParams::Entities::Title.cast(original_params[:title]),
description: ConvenientService::Examples::Standard::V1::RequestParams::Entities::Description.cast(original_params[:description]),
tags: [ConvenientService::Examples::Standard::V1::RequestParams::Entities::Tag.cast(original_params[:tags])],
sources: [ConvenientService::Examples::Standard::V1::RequestParams::Entities::Source.cast(original_params[:sources])]
}
end
let(:casted_params) do
{
id: ConvenientService::Examples::Standard::V1::RequestParams::Entities::ID.cast(original_params[:id]),
format: ConvenientService::Examples::Standard::V1::RequestParams::Entities::Format.cast(original_params[:format]),
title: ConvenientService::Examples::Standard::V1::RequestParams::Entities::Title.cast(original_params[:title]),
description: ConvenientService::Examples::Standard::V1::RequestParams::Entities::Description.cast(original_params[:description]),
tags: [ConvenientService::Examples::Standard::V1::RequestParams::Entities::Tag.cast(original_params[:tags])],
sources: [ConvenientService::Examples::Standard::V1::RequestParams::Entities::Source.cast(original_params[:sources])]
}
end

it "returns success with original and casted params" do
expect(result).to be_success.with_data(original_params: original_params, casted_params: casted_params)
it "returns `success` with original and casted params" do
expect(result).to be_success.with_data(original_params: original_params, casted_params: casted_params)
end
end
end
end
Expand Down
Loading

0 comments on commit fff27d0

Please sign in to comment.