Skip to content

Instantly share code, notes, and snippets.

@ClayShentrup
Created January 22, 2021 19:41
Show Gist options
  • Select an option

  • Save ClayShentrup/c8bc73db185a82f4565de387e071710a to your computer and use it in GitHub Desktop.

Select an option

Save ClayShentrup/c8bc73db185a82f4565de387e071710a to your computer and use it in GitHub Desktop.

Revisions

  1. ClayShentrup created this gist Jan 22, 2021.
    166 changes: 166 additions & 0 deletions testing_helpers.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,166 @@
    # frozen_string_literal: true

    RSpec.shared_context('customer_records') do
    let!(:customer_record_model) do
    stub_const('CustomerRecord', Class.new(AbstractCustomerRecord))
    .tap { |model| model.establish_connection(test_db) }
    end
    let!(:customer_record_factory) do
    FactoryBot::Factory.new(:customer_record)
    end

    attr_reader(:test_db)
    end

    # Base class so we can make a customer_record model that runs on the test
    # customer database instead of our actual test database whose schema we don't
    # want to mess up.
    class AbstractCustomerRecord < ActiveRecord::Base
    self.abstract_class = true

    class << self
    def establish_connection(test_db)
    super(
    adapter: test_db.adapter,
    database: test_db.database,
    host: test_db.host,
    port: test_db.port,
    username: test_db.username,
    password: test_db.password,
    )
    end
    end
    end

    RSpec.shared_context('with postgres origin db') do
    let(:database_type) { 'postgres' }

    append_before do |example|
    assign_database_cleaner_strategy_for_model(
    customer_record_model,
    example.metadata,
    )
    end

    def prepare_database; end

    before(:all) do
    @test_db = CreateTestPostgresCustomerDatabase.call
    end

    after(:all) do
    test_db.teardown
    end
    end

    # Creates and launches a new disposable Postgres DB in /tmp, so we don't mess
    # up our test DB schema for simulating Yoinkitron interactions with customer
    # databases.
    class CreateTestPostgresCustomerDatabase < MethodObject
    def call
    create_customer_records_table
    TestPostgresDatabase.new(pg_tester)
    end

    def pg_tester
    @pg_tester ||= PgTester.new(data_dir: Dir.mktmpdir).tap(&:setup)
    end

    def create_customer_records_table
    pg_tester.exec(<<~SQL)
    CREATE TABLE customer_records (
    id SERIAL PRIMARY KEY,
    created_at timestamp without time zone,
    updated_at timestamp without time zone,
    title character varying(255)
    )
    SQL
    end
    end

    # Presenter for a PgTester instance, providing names that match the ActiveRecord
    # `establish_connection` keyword args
    class TestPostgresDatabase
    def initialize(pg_tester)
    @pg_tester = pg_tester
    end

    delegate(:database, :host, :port, :teardown, to: :pg_tester)

    def adapter
    'postgresql'
    end

    def username
    @pg_tester.user
    end

    def password
    ''
    end

    private

    attr_reader(:pg_tester)
    end

    RSpec.shared_context('with redshift origin db') do
    let(:database_type) { 'redshift' }

    before(:all) do
    @test_db = TestRedshiftDatabase.new
    end

    def prepare_database
    create_customer_records_table
    end

    after do
    drop_customer_records_table
    end

    def create_customer_records_table
    CustomerRecord.connection.execute(<<~SQL)
    CREATE TABLE customer_records (
    id integer PRIMARY KEY,
    created_at timestamp without time zone,
    updated_at timestamp without time zone,
    title character varying(255)
    )
    SQL
    end

    def drop_customer_records_table
    CustomerRecord.connection.execute(<<~SQL)
    DROP TABLE customer_records;
    SQL
    end
    end

    # Presenter for a redshift instance, providing names that match the ActiveRecord
    # `establish_connection` keyword args
    class TestRedshiftDatabase
    def database
    'datebase_name'
    end

    def host
    'hostname'
    end

    def port
    5439
    end

    def adapter
    'redshift'
    end

    def username
    'joe_black'
    end

    def password
    ScopeEnv.get('DEV_SHARED_REDSHIFT_PASSWORD')
    end
    end