From cf27ad8c73ad0e051ac528bd6639be9c3091fd25 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Tue, 16 Apr 2019 20:12:37 +1000 Subject: [PATCH] feat: seed app with example data on first startup --- lib/pact_broker/app.rb | 22 +++++++ lib/pact_broker/configuration.rb | 10 ++- lib/pact_broker/db/seed/pact_1.json | 35 +++++++++++ lib/pact_broker/db/seed/pact_2.json | 40 ++++++++++++ lib/pact_broker/db/seed/pact_3.json | 76 +++++++++++++++++++++++ lib/pact_broker/db/seed_example_data.rb | 58 +++++++++++++++++ lib/pact_broker/test/test_data_builder.rb | 9 +-- spec/service_consumers/pact_helper.rb | 2 +- 8 files changed, 245 insertions(+), 7 deletions(-) create mode 100644 lib/pact_broker/db/seed/pact_1.json create mode 100644 lib/pact_broker/db/seed/pact_2.json create mode 100644 lib/pact_broker/db/seed/pact_3.json create mode 100644 lib/pact_broker/db/seed_example_data.rb diff --git a/lib/pact_broker/app.rb b/lib/pact_broker/app.rb index c25996146..4618c93ca 100644 --- a/lib/pact_broker/app.rb +++ b/lib/pact_broker/app.rb @@ -33,6 +33,8 @@ def initialize &block yield configuration post_configure prepare_database + load_configuration_from_database + seed_example_data end # Allows middleware to be inserted at the bottom of the shared middlware stack @@ -92,6 +94,11 @@ def prepare_database PactBroker::Webhooks::Service.fail_retrying_triggered_webhooks end + def load_configuration_from_database + require 'pact_broker/config/load' + PactBroker::Config::Load.call(configuration) + end + def configure_database_connection PactBroker::DB.connection = configuration.database_connection PactBroker::DB.connection.timezone = :utc @@ -103,6 +110,21 @@ def configure_database_connection Sequel.typecast_timezone = :utc # If no timezone specified on dates going into the database, assume they are UTC end + def seed_example_data + if configuration.seed_example_data && configuration.example_data_seeder + logger.info "Seeding example data" + configuration.example_data_seeder.call + logger.info "Marking seed as done" + configuration.seed_example_data = false + require 'pact_broker/config/save' + PactBroker::Config::Save.call(configuration, [:seed_example_data]) + else + logger.info "Not seeding example data" + end + rescue StandardError => e + logger.error "Error running example data seeder, #{e.class} #{e.message}", e + end + def prepare_app configure_middleware diff --git a/lib/pact_broker/configuration.rb b/lib/pact_broker/configuration.rb index ce69edd80..cf39c4cd2 100644 --- a/lib/pact_broker/configuration.rb +++ b/lib/pact_broker/configuration.rb @@ -29,10 +29,11 @@ class Configuration :webhook_http_method_whitelist, :webhook_scheme_whitelist, :webhook_host_whitelist, - :base_equality_only_on_content_that_affects_verification_results + :base_equality_only_on_content_that_affects_verification_results, + :seed_example_data ] - attr_accessor :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection + attr_accessor :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :example_data_seeder, :seed_example_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser, :sha_generator attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date attr_accessor :check_for_potential_duplicate_pacticipant_names @@ -72,6 +73,11 @@ def self.default_configuration config.html_pact_renderer = default_html_pact_render config.version_parser = PactBroker::Versions::ParseSemanticVersion config.sha_generator = PactBroker::Pacts::GenerateSha + config.seed_example_data = true + config.example_data_seeder = lambda do + require 'pact_broker/db/seed_example_data' + PactBroker::DB::SeedExampleData.call + end config.base_equality_only_on_content_that_affects_verification_results = true config.order_versions_by_date = true config.semver_formats = ["%M.%m.%p%s%d", "%M.%m", "%M"] diff --git a/lib/pact_broker/db/seed/pact_1.json b/lib/pact_broker/db/seed/pact_1.json new file mode 100644 index 000000000..87f075a32 --- /dev/null +++ b/lib/pact_broker/db/seed/pact_1.json @@ -0,0 +1,35 @@ +{ + "consumer": { + "name": "Zoo App" + }, + "provider": { + "name": "Animal Service" + }, + "interactions": [ + { + "description": "a request for an alligator", + "providerState": "there is an alligator named Mary", + "request": { + "method": "get", + "path": "/alligators/Mary", + "headers": { + "Accept": "application/json" + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json;charset=utf-8" + }, + "body": { + "name": "Mary" + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} \ No newline at end of file diff --git a/lib/pact_broker/db/seed/pact_2.json b/lib/pact_broker/db/seed/pact_2.json new file mode 100644 index 000000000..9105482b9 --- /dev/null +++ b/lib/pact_broker/db/seed/pact_2.json @@ -0,0 +1,40 @@ +{ + "consumer": { + "name": "Zoo App" + }, + "provider": { + "name": "Animal Service" + }, + "interactions": [ + { + "description": "a request for an alligator", + "providerState": "there is an alligator named Mary", + "request": { + "method": "get", + "path": "/alligators/Mary", + "headers": { + "Accept": "application/json" + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json;charset=utf-8" + }, + "body": { + "name": "Mary" + }, + "matchingRules": { + "$.body.name": { + "match": "type" + } + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} \ No newline at end of file diff --git a/lib/pact_broker/db/seed/pact_3.json b/lib/pact_broker/db/seed/pact_3.json new file mode 100644 index 000000000..8c556e4de --- /dev/null +++ b/lib/pact_broker/db/seed/pact_3.json @@ -0,0 +1,76 @@ +{ + "consumer": { + "name": "Zoo App" + }, + "provider": { + "name": "Animal Service" + }, + "interactions": [ + { + "description": "a request for an alligator", + "providerState": "there is an alligator named Mary", + "request": { + "method": "get", + "path": "/alligators/Mary", + "headers": { + "Accept": "application/json" + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json;charset=utf-8" + }, + "body": { + "name": "Mary" + }, + "matchingRules": { + "$.body.name": { + "match": "type" + } + } + } + }, + { + "description": "a request for an alligator", + "providerState": "there is not an alligator named Mary", + "request": { + "method": "get", + "path": "/alligators/Mary", + "headers": { + "Accept": "application/json" + } + }, + "response": { + "status": 404, + "headers": { + } + } + }, + { + "description": "a request for an alligator", + "providerState": "an error occurs retrieving an alligator", + "request": { + "method": "get", + "path": "/alligators/Mary", + "headers": { + "Accept": "application/json" + } + }, + "response": { + "status": 500, + "headers": { + "Content-Type": "application/json;charset=utf-8" + }, + "body": { + "error": "Argh!!!" + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} \ No newline at end of file diff --git a/lib/pact_broker/db/seed_example_data.rb b/lib/pact_broker/db/seed_example_data.rb new file mode 100644 index 000000000..a04da0b30 --- /dev/null +++ b/lib/pact_broker/db/seed_example_data.rb @@ -0,0 +1,58 @@ +require 'pact_broker/test/test_data_builder' + +module PactBroker + module DB + class SeedExampleData + def self.call + new.call + end + + def call + PactBroker::Test::TestDataBuilder.new + .create_consumer("Example App", created_at: days_ago(16)) + .create_provider("Example API", created_at: days_ago(16)) + .create_consumer_version("e15da45d3943bf10793a6d04cfb9f5dabe430fe2", created_at: days_ago(16)) + .create_consumer_version_tag("prod", created_at: days_ago(16)) + .create_consumer_version_tag("dev", created_at: days_ago(16)) + .create_pact(json_content: pact_1, created_at: days_ago(16)) + .create_verification(provider_version: "1315e0b1924cb6f42751f977789be3559373033a", success: false, execution_date: days_ago(15)) + .create_provider_version_tag("dev", created_at: days_ago(14)) + .create_verification(provider_version: "480e5aeb30467856ca995d0024d2c1800b0719e5", number: 2, execution_date: days_ago(14)) + .create_provider_version_tag("prod", created_at: days_ago(14)) + .create_provider_version_tag("dev", created_at: days_ago(14)) + .create_consumer_version("725c6ccb7cf7efc51b4394f9828585eea9c379d9", created_at: days_ago(7)) + .create_consumer_version_tag("feat-new-thing", created_at: days_ago(7)) + .create_pact(json_content: pact_2, created_at: days_ago(7)) + .create_consumer_version("7bd4d9173522826dc3e8704fd62dde0424f4c827", created_at: days_ago(1)) + .create_consumer_version_tag("dev", created_at: days_ago(1)) + .create_pact(json_content: pact_3, created_at: days_ago(1)) + .create_verification(provider_version: "4fdf20082263d4c5038355a3b734be1c0054d1e1", execution_date: days_ago(1)) + .create_provider_version_tag("dev", created_at: days_ago(1)) + end + + def pact_1 + seed_data_file("pact_1.json") + end + + def pact_2 + seed_data_file("pact_2.json") + end + + def pact_3 + seed_data_file("pact_3.json") + end + + def seed_data_dir + File.join(File.dirname(__FILE__), "seed") + end + + def seed_data_file(name) + File.read(File.join(seed_data_dir, name)) + end + + def days_ago(days) + DateTime.now - days + end + end + end +end diff --git a/lib/pact_broker/test/test_data_builder.rb b/lib/pact_broker/test/test_data_builder.rb index 09d005d59..7fbd6d198 100644 --- a/lib/pact_broker/test/test_data_builder.rb +++ b/lib/pact_broker/test/test_data_builder.rb @@ -189,18 +189,21 @@ def use_provider_version version_number def create_tag tag_name, params = {} params.delete(:comment) @tag = PactBroker::Domain::Tag.create(name: tag_name, version: @version) + set_created_at_if_set params[:created_at], :tags, { name: @tag.name, version_id: @tag.version_id } self end def create_consumer_version_tag tag_name, params = {} params.delete(:comment) @tag = PactBroker::Domain::Tag.create(name: tag_name, version: @consumer_version) + set_created_at_if_set params[:created_at], :tags, { name: @tag.name, version_id: @tag.version_id } self end def create_provider_version_tag tag_name, params = {} params.delete(:comment) @tag = PactBroker::Domain::Tag.create(name: tag_name, version: @provider_version) + set_created_at_if_set params[:created_at], :tags, { name: @tag.name, version_id: @tag.version_id } self end @@ -343,10 +346,10 @@ def set_created_at_if_set created_at, table_name, selector def default_json_content { - "consumer" => { + "consumer" => { "name" => "Condor" }, - "provider" => { + "provider" => { "name" => "Pricing Service" }, "interactions" => [], @@ -354,7 +357,5 @@ def default_json_content }.to_json end end - end end - diff --git a/spec/service_consumers/pact_helper.rb b/spec/service_consumers/pact_helper.rb index 75871e9f6..cbcf293d9 100644 --- a/spec/service_consumers/pact_helper.rb +++ b/spec/service_consumers/pact_helper.rb @@ -6,7 +6,7 @@ require 'tasks/database' require 'pact_broker/db' PactBroker::DB.connection = PactBroker::Database.database = DB::PACT_BROKER_DB - +PactBroker.configuration.seed_example_data = false require 'spec/support/database_cleaner' require 'pact_broker' require 'pact_broker/app'