diff --git a/README.adoc b/README.adoc index 51084431..02ae1052 100644 --- a/README.adoc +++ b/README.adoc @@ -138,6 +138,8 @@ bin/setup == Upgrade +‼️ If upgrading to Terminus 0.55.0 or higher, please make sure to run the `bin/exchangize` script to upgrade your extensions to use exchanges so you can manage multiple HTTP requests/responses. _You only need to do this once_. ‼️ + To upgrade this project for local development, run: [source,bash] diff --git a/app/aspects/extensions/upgrader.rb b/app/aspects/extensions/upgrader.rb new file mode 100644 index 00000000..70540255 --- /dev/null +++ b/app/aspects/extensions/upgrader.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require "refinements/hash" + +module Terminus + module Aspects + module Extensions + # Automates upgrading poll extensions to use exchanges. + class Upgrader + include Deps[ + :logger, + extension_repository: "repositories.extension", + exchange_repository: "repositories.extension_exchange" + ] + + using Refinements::Hash + + def call + extension_repository.where(kind: "poll").each do |extension| + create_exchange extension + logger.info { "Upgraded extension: #{extension.id}." } + end + end + + def create_exchange extension + attributes = extension.to_h + .slice(:headers, :verb, :uris, :body) + .transform_keys!(uris: :template) + .transform_value!(:template) { it.join "\n" } + + exchange_repository.create extension_id: extension.id, **attributes + end + end + end + end +end diff --git a/bin/exchangize b/bin/exchangize new file mode 100755 index 00000000..5bbf8016 --- /dev/null +++ b/bin/exchangize @@ -0,0 +1,9 @@ +#! /usr/bin/env ruby +# frozen_string_literal: true + +require "bundler/setup" +Bundler.require :tools + +require "hanami/prepare" + +Hanami.app["aspects.extensions.upgrader"].call diff --git a/spec/app/aspects/extensions/upgrader_spec.rb b/spec/app/aspects/extensions/upgrader_spec.rb new file mode 100644 index 00000000..328a4f3e --- /dev/null +++ b/spec/app/aspects/extensions/upgrader_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "hanami_helper" + +RSpec.describe Terminus::Aspects::Extensions::Upgrader, :db do + subject(:upgrader) { described_class.new } + + include_context "with application dependencies" + + let :extension do + Factory[ + :extension, + headers: {accept: "application/json"}, + verb: "post", + uris: %w[https://test.io/1 https://test.io/2], + body: {sort: :desc} + ] + end + + let(:repository) { Terminus::Repositories::ExtensionExchange.new } + + describe "#call" do + it "adds extension exchanges" do + extension + upgrader.call + + expect(repository.all.map(&:to_h)).to match( + [ + hash_including( + headers: {"accept" => "application/json"}, + verb: "post", + template: "https://test.io/1\nhttps://test.io/2", + body: {"sort" => "desc"} + ) + ] + ) + end + + it "logs info" do + extension + upgrader.call + expect(logger.reread).to match(/INFO.+Upgraded extension: #{extension.id}/) + end + end + + context "with non-poll extensions" do + before do + Factory[:extension, kind: "static"] + upgrader.call + end + + it "adds extension exchanges" do + expect(repository.all).to eq([]) + end + + it "logs info" do + expect(logger.reread).not_to match(/INFO.+Upgraded extension/) + end + end +end