From 8f49fe8d648aa4a429de1c582202c09801188baa Mon Sep 17 00:00:00 2001 From: Eduardo Candanedo Date: Sun, 18 Feb 2024 16:17:41 -0600 Subject: [PATCH] Basic gem specs --- .rubocop.yml | 5 +++ spec/fixtures/random_private_key.pem | 27 +++++++++++ spec/use_paragon/base_spec.rb | 62 ++++++++++++++++++++++++++ spec/use_paragon/configuration_spec.rb | 60 +++++++++++++++++++++++++ spec/use_paragon/integration_spec.rb | 35 +++++++++++++++ spec/use_paragon/user_spec.rb | 30 +++++++++++++ spec/use_paragon/workflow_spec.rb | 41 +++++++++++++++++ spec/use_paragon_spec.rb | 55 +++++++++++++++++++++++ 8 files changed, 315 insertions(+) create mode 100644 spec/fixtures/random_private_key.pem create mode 100644 spec/use_paragon/base_spec.rb create mode 100644 spec/use_paragon/configuration_spec.rb create mode 100644 spec/use_paragon/integration_spec.rb create mode 100644 spec/use_paragon/user_spec.rb create mode 100644 spec/use_paragon/workflow_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index e43b884..10aedf7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,3 +11,8 @@ Style/StringLiteralsInInterpolation: Layout/LineLength: Max: 100 + +Metrics/BlockLength: + Enabled: true + Exclude: + - 'spec/**/*_spec.rb' # Exclude block length check for spec files diff --git a/spec/fixtures/random_private_key.pem b/spec/fixtures/random_private_key.pem new file mode 100644 index 0000000..acc72d3 --- /dev/null +++ b/spec/fixtures/random_private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyTPdZoXv5V8UKnZ7T+w7qQjnBdSYYDkRgXRuUn0Y2Ss3xY5f +n+FLc/NF7AbOu1q+Xc4F6l3vlEO01i1zHcvVVZIsaCzdEyIsM0mk/zI5mM4xFJnS +tWYfP3hcZiZj8YP78zqFY0u8EY5QugzcDRyOWuKEuJWeCHyAeCpwC6ROtRW4dRpx +ukJUP4L/EKfG15zqHsQ/VYfycDqZBnZ7k3Xp69X+FWwX2QLaPfUCOawwOMF9xvaJ +4M8/lhBjtQRlE2t8mO4y/xyA5E7rvqI9r6Gf4lwN40kDhObAJgqXj55sxT36HN6m +YOdMjpBtDeM9YSf3qNeu0XP8NoK9jjz9jLcGswIDAQABAoIBAH3ceC/9roRDF6Kd +z9m+qC4/V7mVDDGFk0DvS5H0z1K0lOG3w/1nZUFqY9UZRluo3DBO6J5hVapm65Zs +Uo2ivOH+wL6QqY8a/Sf6G6DOyFlDA6A2P7H2Fs5BlR24zJ5/8aHysqDlDQsISf2x +BYCCo3PBljWMyol7vgXAOc9rx0NZaW1OVGqoKk1aLBxYiw/uqBd/TyQ84RAOxowG +/FB8FO59MeQXHrXvgvGv3ZjH/Tzuj2hKgLY5tT7Aix2vLdSZRA9GybsnmUQmZw9g +T2zm3L37itKS6kPvL7LC7fGZ2Av3/Hm7C5Zvm+f4uNO43tgVJwUchZMf6GkmC8QB +R6I16iECgYEA/SAaZc65pARfKQmMnG1Sg5ICkLqG0r8+3Lfi8NMTuJFjU/Pvfb4y +y/8bK5w3znto5x9mL4OV6+qJxc7f1jfi7uErwHhfpq8Y0n6OT9IElR7Xs7fis7Zb +gJAbFtdZkQs2XKNGrr+0r1UkREIa/CXk30zSz1NB6RKU16UioKvA8kMCgYEA2BCE +H4XCQNE+L9qX+PBVtx/JtHkUkCKP67nWb7he0dTXGeY5o/8T7LM6VlId5hMmpqMo +8RXLNs0V67KqZyO1JLl9/CeK76iDXPp+5L0WJ+u2uX+rlgxN0/qdJF2G7mfECk+3 +d1IDzFvOEVwab+WGpMWeLd7BmnxX0sDhsKwXXEUCgYEAsofge3w5XOjJ18uRjSnA +ojuyI0Lh4kElVPlb4W3F4pZfcBlpLg7AyoJFJmzvj4WJz9DRJntWKuhf8ZTXx4to +1lv3Z8F9cd7GZiXcAdCf4gA32mr1tI3TJ8pl7eD2F5vaAIGS0SJr2hqHwzKdgn+Z +9lVcqTeo2eRrQoMy2zgXg5ECgYB5/lUN6jGhWf4CK/2IO9XiebZf8y95L0dFSJiQ +Vv/IWzoP5XDFRDPzfcEha4TcD8XWWOzQQ4vFdpFCtHzVeOwwpfsj4GgTW4cjJqS+ +BeS2qYmycXNcqSqAQQ2H4MbZkRwGVGFBqOyUxkGJWSlKgKb24i+laRRlMCEYz6ij +EYDbCQKBgQCCq0b9hl2LcPQ3Ymjq0OQg52JmqfIoFAzGtoftuqkYUG5BZy5PE/OZ +vX0QQ+j2T0cKKPpvJOsCXTYBJJ8HTAmsPR8H2BB6pY2PSvcV4k1Ydgs7NG+o8lEf ++PL0P6b9SsSDouDmczTWFP16Lc8yOUVFr5ABTf0M23HN7oDCb/GC5g== +-----END RSA PRIVATE KEY----- diff --git a/spec/use_paragon/base_spec.rb b/spec/use_paragon/base_spec.rb new file mode 100644 index 0000000..e4c5e65 --- /dev/null +++ b/spec/use_paragon/base_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +RSpec.describe UseParagon::Base do + let(:user_id) { 123 } + let(:base_instance) { described_class.new(user_id) } + + before do + # Set up the configuration for testing + UseParagon.configure do |config| + config.private_key = File.read(random_private_key_path) + config.project_id = "test_project_id" + end + end + + describe "#initialize" do + it "initializes with a user_id" do + expect(base_instance.user_id).to eq(user_id) + end + end + + describe "#generate_token" do + it "raises an error when user_id is nil" do + expect do + described_class.new(nil).generate_token + end.to raise_error(UseParagon::InvalidUserIdError) + end + + it "raises an error when user_id is blank" do + expect do + described_class.new("").generate_token + end.to raise_error(UseParagon::InvalidUserIdError) + end + + it "generates a valid JWT token when user is valid" do + token = base_instance.generate_token + expect(token).not_to be_nil + end + end + + describe "#connection" do + it "creates a Faraday connection with correct configuration" do + connection = base_instance.send(:connection) + expect(connection).to be_a(Faraday::Connection) + expect(connection.url_prefix.to_s).to eq("#{UseParagon.configuration.base_url}/") + expect(connection.builder.handlers).to include(Faraday::Request::Authorization) + expect(connection.builder.handlers).to include(Faraday::Response::Logger) + end + end + + describe "#path" do + it "returns the correct endpoint path" do + endpoint = "some/random/endpoint" + expected_path = "/projects/test_project_id/#{endpoint}" + + expect(base_instance.send(:path, endpoint)).to eq(expected_path) + end + end + + def random_private_key_path + File.expand_path("../fixtures/random_private_key.pem", __dir__) + end +end diff --git a/spec/use_paragon/configuration_spec.rb b/spec/use_paragon/configuration_spec.rb new file mode 100644 index 0000000..bbde712 --- /dev/null +++ b/spec/use_paragon/configuration_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "logger" + +RSpec.describe UseParagon::Configuration do + let(:configuration) { described_class.new } + + describe "#initialize" do + it "initializes with no default private_key" do + expect(configuration.private_key).to be_nil + end + + it "initializes with no default project_id" do + expect(configuration.project_id).to be_nil + end + + it "initializes with default base_url" do + expect(configuration.base_url).to eq("https://zeus.useparagon.com") + end + + it "initializes with default logger" do + expect(configuration.logger).to be_a(Logger) + end + + it "initializes with default logger_enabled" do + expect(configuration.logger_enabled).to be(true) + end + end + + describe "attributes" do + it "allows setting and getting private_key" do + configuration.private_key = "some_key" + expect(configuration.private_key).to eq("some_key") + end + + it "allows setting and getting project_id" do + configuration.project_id = "some_id" + expect(configuration.project_id).to eq("some_id") + end + + it "allows setting and getting base_url" do + configuration.base_url = "http://example.com" + expect(configuration.base_url).to eq("http://example.com") + end + + it "allows setting and getting logger" do + default_logger = configuration.logger + configured_logger = Logger.new(STDOUT) + configuration.logger = configured_logger + + expect(configuration.logger).to eq(configured_logger) + expect(default_logger).not_to eq(configured_logger) + end + + it "allows setting and getting logger_enabled" do + configuration.logger_enabled = false + expect(configuration.logger_enabled).to be(false) + end + end +end diff --git a/spec/use_paragon/integration_spec.rb b/spec/use_paragon/integration_spec.rb new file mode 100644 index 0000000..d4143bb --- /dev/null +++ b/spec/use_paragon/integration_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +RSpec.describe UseParagon::Integration do + let(:integration) { described_class.new(123) } + + describe "#metadata" do + it "calls the correct endpoint" do + expect(integration).to receive(:path).with("sdk/metadata") + .and_return("/projects/123/sdk/metadata") + expect(integration).to receive(:connection) + .and_return(double("connection", get: true)) + integration.metadata + end + end + + describe "#list" do + it "calls the correct endpoint" do + expect(integration).to receive(:path).with("sdk/integrations") + .and_return("/projects/123/sdk/integrations") + expect(integration).to receive(:connection) + .and_return(double("connection", get: true)) + integration.list + end + end + + describe "#uninstall" do + it "calls the correct endpoint" do + expect(integration).to receive(:path).with("sdk/integrations/456") + .and_return("/projects/123/sdk/integrations/456") + expect(integration).to receive(:connection) + .and_return(double("connection", delete: true)) + integration.uninstall(456) + end + end +end diff --git a/spec/use_paragon/user_spec.rb b/spec/use_paragon/user_spec.rb new file mode 100644 index 0000000..1b0e695 --- /dev/null +++ b/spec/use_paragon/user_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +RSpec.describe UseParagon::User do + let(:user) { described_class.new(123) } + + describe "#get" do + it "calls the correct endpoint" do + expect(user).to receive(:path).with("sdk/me").and_return("/projects/123/sdk/me") + expect(user).to receive(:connection).and_return(double("connection", get: true)) + user.get + end + end + + describe "#metadata=" do + it "calls the correct endpoint with patch method" do + expect(user).to receive(:path).with("sdk/me").and_return("/projects/123/sdk/me") + expect(user).to receive(:connection).and_return(double("connection", patch: true)) + user.metadata = {} + end + end + + describe "#credentials" do + it "calls the correct endpoint" do + expect(user).to receive(:path).with("sdk/credentials") + .and_return("/projects/123/sdk/credentials") + expect(user).to receive(:connection).and_return(double("connection", get: true)) + user.credentials + end + end +end diff --git a/spec/use_paragon/workflow_spec.rb b/spec/use_paragon/workflow_spec.rb new file mode 100644 index 0000000..6d94b91 --- /dev/null +++ b/spec/use_paragon/workflow_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +RSpec.describe UseParagon::Workflow do + let(:workflow) { described_class.new(123) } + + describe "#request" do + it "calls the correct endpoint with post method" do + expect(workflow).to receive(:path).with("sdk/triggers/789") + .and_return("/projects/123/sdk/triggers/789") + expect(workflow).to receive(:connection).and_return(double("connection", post: true)) + workflow.request(789) + end + end + + describe "#proxy_request" do + it "calls the correct endpoint with post method" do + expect(workflow).to receive(:path).with("sdk/proxy/some_type/some_path") + .and_return("/projects/123/sdk/proxy/some_type/some_path") + expect(workflow).to receive(:connection).and_return(double("connection", post: true)) + workflow.proxy_request("some_type", "some_path", {}) + end + end + + describe "#event" do + it "calls the correct endpoint with post method" do + expect(workflow).to receive(:path).with("sdk/events/trigger") + .and_return("/projects/123/sdk/events/trigger") + expect(workflow).to receive(:connection).and_return(double("connection", post: true)) + workflow.event("some_event", {}) + end + end + + describe "#disable" do + it "calls the correct endpoint with delete method" do + expect(workflow).to receive(:path).with("sdk/workflows/abc") + .and_return("/projects/123/sdk/workflows/abc") + expect(workflow).to receive(:connection).and_return(double("connection", delete: true)) + workflow.disable("abc") + end + end +end diff --git a/spec/use_paragon_spec.rb b/spec/use_paragon_spec.rb index 7dd2888..f26ebbf 100644 --- a/spec/use_paragon_spec.rb +++ b/spec/use_paragon_spec.rb @@ -4,4 +4,59 @@ it "has a version number" do expect(UseParagon::VERSION).not_to be nil end + + describe ".load!" do + context "when running in a Rails environment" do + it "registers Rails engine" do + allow(UseParagon).to receive(:rails?).and_return(true) + expect(UseParagon).to receive(:register_rails_engine) + UseParagon.load! + end + end + + context "when not running in a Rails environment" do + it "does not register Rails engine" do + allow(UseParagon).to receive(:rails?).and_return(false) + expect(UseParagon).not_to receive(:register_rails_engine) + UseParagon.load! + end + end + end + + describe ".configuration" do + it "returns a configuration object" do + expect(UseParagon.configuration).to be_an_instance_of(UseParagon::Configuration) + end + end + + describe ".configure" do + it "yields the configuration object" do + expect { |block| UseParagon.configure(&block) }.to yield_with_args(UseParagon.configuration) + end + end + + # Investigate why this test is failing + describe ".load!" do + context "when Rails is present" do + before do + allow(UseParagon).to receive(:rails?).and_return(true) + end + + it "registers the Rails engine" do + expect(UseParagon).to receive(:register_rails_engine) + UseParagon.load! + end + end + + context "when Rails is not present" do + before do + allow(UseParagon).to receive(:rails?).and_return(false) + end + + it "does not register the Rails engine" do + expect(UseParagon).not_to receive(:register_rails_engine) + UseParagon.load! + end + end + end end