zeebe_bpmn_rspec 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +137 -0
- data/docker-compose.yml +3 -3
- data/lib/zeebe_bpmn_rspec.rb +7 -1
- data/lib/zeebe_bpmn_rspec/activated_job.rb +36 -7
- data/lib/zeebe_bpmn_rspec/helpers.rb +39 -18
- data/lib/zeebe_bpmn_rspec/matchers/have_activated.rb +99 -0
- data/lib/zeebe_bpmn_rspec/matchers/have_headers.rb +15 -0
- data/lib/zeebe_bpmn_rspec/matchers/have_variables.rb +15 -0
- data/lib/zeebe_bpmn_rspec/version.rb +1 -1
- data/zeebe_bpmn_rspec.gemspec +3 -1
- metadata +9 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 28a2727e47b273a44521d2f74ecf03c97ee84c22ccd9c2d16cd70eb97e2a2b3f
         | 
| 4 | 
            +
              data.tar.gz: '065783a4f62345e2fa7b7a121d090153bdbf67e3b683c2156c40e74238e862b6'
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 50711d2a17a5141d4734e5bcc40d10c73b7a43e369561ad74cbdb60de3d6631f804f175f777aed911a369d5aeaf4be619772d330d7c54ab26b8b24bc1d033f24
         | 
| 7 | 
            +
              data.tar.gz: f81b79f8603d00b9c8714a85dd6d927e3e13c4b14d8f204e5dd0eeb172a4c04952e90f8d7419d20a788647125c9e362bb3ed81cd116cd6320414c2ebc2436503
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,28 @@ | |
| 1 1 | 
             
            # zeebe_bpmn_rspec
         | 
| 2 2 |  | 
| 3 | 
            +
            ## v0.5.0
         | 
| 4 | 
            +
            - Require Ruby 2.6 or later.
         | 
| 5 | 
            +
            - Require `worker` to be specified when activating a job. This argument is
         | 
| 6 | 
            +
              defaulted but can no longer be specified as blank.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            ## v0.4.1
         | 
| 9 | 
            +
            - Allow `with_workflow_instance` to be called without a block.
         | 
| 10 | 
            +
            - Allow `worker` to be specified when activating a job.
         | 
| 11 | 
            +
            - Expose `workflow_instance_key` for activated jobs.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            ## v0.4.0
         | 
| 14 | 
            +
            - Add `ttl_ms` option for `publish_message`.
         | 
| 15 | 
            +
            - Add `update_retries` method to `ActivatedJob` class.
         | 
| 16 | 
            +
            - Add `set_variables` helper.
         | 
| 17 | 
            +
            - Add support for `:fetch_variables` option when activating jobs.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ## v0.3.1
         | 
| 20 | 
            +
            - Use consistent activate request timeout.
         | 
| 21 | 
            +
            - Provide a better error when a job is not activated.
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## v0.3.0
         | 
| 24 | 
            +
            - Add custom matchers, `have_variables`, `have_headers`, and `have_activated`.
         | 
| 25 | 
            +
             | 
| 3 26 | 
             
            ## v0.2.0
         | 
| 4 27 | 
             
            - Add `retries` option to `ActivatedJob#and_fail`.
         | 
| 5 28 | 
             
            - Add method aliases: `and_complete` (`complete`), `and_fail` (`fail`), `and_throw_error` (`throw_error`).
         | 
    
        data/README.md
    CHANGED
    
    | @@ -39,6 +39,8 @@ end | |
| 39 39 |  | 
| 40 40 | 
             
            The gem adds the following helper methods to RSpec.
         | 
| 41 41 |  | 
| 42 | 
            +
            The gem also defines [Custom Matchers](#custom-matchers).
         | 
| 43 | 
            +
             | 
| 42 44 | 
             
            ### Deploy Workflow
         | 
| 43 45 |  | 
| 44 46 | 
             
            The `deploy_workflow` method requires a path to a BPMN file and deploys it to Zeebe. There is no support for
         | 
| @@ -155,6 +157,16 @@ job = activate_job("my_job") | |
| 155 157 | 
             
            job.fail(retries: 1)
         | 
| 156 158 | 
             
            ```
         | 
| 157 159 |  | 
| 160 | 
            +
            #### Update Retries
         | 
| 161 | 
            +
             | 
| 162 | 
            +
            The retries for a job can also be modified using the `update_retries` method:
         | 
| 163 | 
            +
             | 
| 164 | 
            +
            ```ruby
         | 
| 165 | 
            +
            job = activate_job("my_job")
         | 
| 166 | 
            +
             | 
| 167 | 
            +
            job.update_retries(3)
         | 
| 168 | 
            +
            ```
         | 
| 169 | 
            +
             | 
| 158 170 | 
             
            #### Throw Error
         | 
| 159 171 |  | 
| 160 172 | 
             
            The `and_throw_error` (also aliased as `throw_error`) method can be used to throw an error for a job. The error code is required and an
         | 
| @@ -217,6 +229,131 @@ publish_message("message_name", correlation_key: expected_value, | |
| 217 229 | 
             
                            variables: { foo: "bar" })
         | 
| 218 230 | 
             
            ```
         | 
| 219 231 |  | 
| 232 | 
            +
            The time-to-live (in milliseconds) cna also be specified for a message.
         | 
| 233 | 
            +
            It defaults to 5000 milliseconds if unspecified.
         | 
| 234 | 
            +
             | 
| 235 | 
            +
            ```ruby
         | 
| 236 | 
            +
            publish_message("message_name", correlation_key: expected_value, ttl_ms: 1000)
         | 
| 237 | 
            +
            ```
         | 
| 238 | 
            +
             | 
| 239 | 
            +
            ### Set Variables
         | 
| 240 | 
            +
             | 
| 241 | 
            +
            The `set_variables` method can be used to set variables for a specified
         | 
| 242 | 
            +
            scope in Zeebe:
         | 
| 243 | 
            +
             | 
| 244 | 
            +
            ```ruby
         | 
| 245 | 
            +
            # workflow_instance_key is a method that returns the key for the current workflow instance
         | 
| 246 | 
            +
            set_variables(workflow_instance_key, { foo: "bar" })
         | 
| 247 | 
            +
            ```
         | 
| 248 | 
            +
             | 
| 249 | 
            +
            An activated job can be used to determine the key for the task that it is associated with:
         | 
| 250 | 
            +
             | 
| 251 | 
            +
            ```ruby
         | 
| 252 | 
            +
            job = job_with_type("my_type")
         | 
| 253 | 
            +
            set_variables(job.task_key, { foo: "baz"})
         | 
| 254 | 
            +
            ```
         | 
| 255 | 
            +
             | 
| 256 | 
            +
            Variables default to being local to the scope on which they are set. This
         | 
| 257 | 
            +
            can be overridden by specifying the `:local` option:
         | 
| 258 | 
            +
             | 
| 259 | 
            +
            ```ruby
         | 
| 260 | 
            +
            set_variables(job.task_key, { foo: "baz"}, local: false)
         | 
| 261 | 
            +
            ```
         | 
| 262 | 
            +
             | 
| 263 | 
            +
            ### Custom Matchers
         | 
| 264 | 
            +
             | 
| 265 | 
            +
            In addition to the helpers documented above, this gem defines custom RSpec matchers to provide a more typical
         | 
| 266 | 
            +
            experience of expectations and matchers.
         | 
| 267 | 
            +
             | 
| 268 | 
            +
            #### expect_job_of_type
         | 
| 269 | 
            +
             | 
| 270 | 
            +
            The `expect_job_of_type` helper is a convenient wrapper to activate a job and set an expectation target.
         | 
| 271 | 
            +
             | 
| 272 | 
            +
            ```ruby
         | 
| 273 | 
            +
            expect_job_of_type("my_type")
         | 
| 274 | 
            +
            ```
         | 
| 275 | 
            +
             | 
| 276 | 
            +
            Similar to the `activate_job` helper, it activates a job and wraps the result in an `ActivatedJob` object.
         | 
| 277 | 
            +
            That object is then passed to `expect()`. Unlike `activate_job`, this helper does not raise if there is no job activated.
         | 
| 278 | 
            +
             | 
| 279 | 
            +
            This is equivalent to `expect(job_with_type("my_type")` or `expect(activate_job("my_type", validate: false))`.
         | 
| 280 | 
            +
             | 
| 281 | 
            +
            `expect_job_of_type` is expected to be used with the matchers below.
         | 
| 282 | 
            +
             | 
| 283 | 
            +
            #### have_activated
         | 
| 284 | 
            +
             | 
| 285 | 
            +
            The `have_activated` matcher checks that the target represents an activated job. It will raise an error if no job
         | 
| 286 | 
            +
            was activated.
         | 
| 287 | 
            +
             | 
| 288 | 
            +
            ```ruby
         | 
| 289 | 
            +
            expect_job_of_type("my_type").to have_activated
         | 
| 290 | 
            +
            ```
         | 
| 291 | 
            +
             | 
| 292 | 
            +
            Various additional methods can be chained on the `have_activated` matcher.
         | 
| 293 | 
            +
             | 
| 294 | 
            +
            The `with_variables` method can be used to check the input variables that the job was activated with:
         | 
| 295 | 
            +
             | 
| 296 | 
            +
            ```ruby
         | 
| 297 | 
            +
            expect_job_of_type("my_type").to have_activated.with_variables(user_id: 123)
         | 
| 298 | 
            +
            ```
         | 
| 299 | 
            +
             | 
| 300 | 
            +
            The `with_headers` method can be used to check the headers that the job was activated with:
         | 
| 301 | 
            +
             | 
| 302 | 
            +
            ```ruby
         | 
| 303 | 
            +
            expect_job_of_type("my_type").to have_activated.with_headers(id_type: "user")
         | 
| 304 | 
            +
            ```
         | 
| 305 | 
            +
             | 
| 306 | 
            +
            The `with_variables` and `with_headers` methods can be chained on the same expectation:
         | 
| 307 | 
            +
             | 
| 308 | 
            +
            ```ruby
         | 
| 309 | 
            +
            expect_job_of_type("my_type").to have_activated.
         | 
| 310 | 
            +
                                               with_variables(user_id: 123).
         | 
| 311 | 
            +
                                               with_headers(id_type: "user")
         | 
| 312 | 
            +
            ```
         | 
| 313 | 
            +
             | 
| 314 | 
            +
            The matcher also supports methods to complete, fail, or throw an error for a job:
         | 
| 315 | 
            +
             | 
| 316 | 
            +
            ```ruby
         | 
| 317 | 
            +
            # Complete
         | 
| 318 | 
            +
            expect_job_of_type("my_type").to have_activated.and_complete
         | 
| 319 | 
            +
             | 
| 320 | 
            +
            # Complete with new variables
         | 
| 321 | 
            +
            expect_job_of_type("my_type").to have_activated.and_complete(result_code: 456)
         | 
| 322 | 
            +
             | 
| 323 | 
            +
            # Fail (sets retries to 0 by default)
         | 
| 324 | 
            +
            expect_job_of_type("my_type").to have_activated.and_fail
         | 
| 325 | 
            +
             | 
| 326 | 
            +
            # Fail and specify retries
         | 
| 327 | 
            +
            expect_job_of_type("my_type").to have_activated.and_fail(retries: 1)
         | 
| 328 | 
            +
             | 
| 329 | 
            +
            # Fail with an error message
         | 
| 330 | 
            +
            expect_job_of_type("my_type").to have_activated.and_fail("boom!")
         | 
| 331 | 
            +
             | 
| 332 | 
            +
            # Fail with an error message and specify retries
         | 
| 333 | 
            +
            expect_job_of_type("my_type").to have_activated.and_fail("boom!", retries: 2)
         | 
| 334 | 
            +
             | 
| 335 | 
            +
            # Throw an error (error code is required)
         | 
| 336 | 
            +
            expect_job_of_type("my_type").to have_activated.and_throw_error("MY_ERROR")
         | 
| 337 | 
            +
             | 
| 338 | 
            +
            # Throw an error with an error message
         | 
| 339 | 
            +
            expect_job_of_type("my_type").to have_activated.and_throw_error("MY_ERROR", "went horribly wrong")
         | 
| 340 | 
            +
            ```
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            Only one of `and_complete`, `and_fail`, or `and_throw_error` can be specified for a single expectation.
         | 
| 343 | 
            +
             | 
| 344 | 
            +
            #### have_variables and have_headers
         | 
| 345 | 
            +
             | 
| 346 | 
            +
            In addition to the `with_variables` and `with_headers` methods that can be chained onto the `have_activated`
         | 
| 347 | 
            +
            matcher, there are matchers that can be used directly to set expectations on the variables or
         | 
| 348 | 
            +
            headers for an `ActivatedJob`.
         | 
| 349 | 
            +
             | 
| 350 | 
            +
            ```ruby
         | 
| 351 | 
            +
            job = activate_job("my_type")
         | 
| 352 | 
            +
             | 
| 353 | 
            +
            expect(job).to have_variables(user: 123)
         | 
| 354 | 
            +
            expect(job).to have_headers(id_type: "user")
         | 
| 355 | 
            +
            ```
         | 
| 356 | 
            +
             | 
| 220 357 | 
             
            ## Tips & Tricks
         | 
| 221 358 |  | 
| 222 359 | 
             
            ### Enumerator for Multiple Jobs
         | 
    
        data/docker-compose.yml
    CHANGED
    
    | @@ -8,7 +8,7 @@ x-environment: &default-environment | |
| 8 8 | 
             
              BUNDLE_DISABLE_SHARED_GEMS: "true"
         | 
| 9 9 | 
             
              ZEEBE_ADDRESS: zeebe:26500
         | 
| 10 10 | 
             
            x-service: &default-service
         | 
| 11 | 
            -
              image: ruby:2. | 
| 11 | 
            +
              image: ruby:2.7.2
         | 
| 12 12 | 
             
              volumes:
         | 
| 13 13 | 
             
                - .:/usr/src/gem
         | 
| 14 14 | 
             
                - ./compose/entrypoint.sh:/tmp/entrypoint.sh
         | 
| @@ -18,7 +18,7 @@ x-service: &default-service | |
| 18 18 | 
             
              stdin_open: true
         | 
| 19 19 | 
             
            services:
         | 
| 20 20 | 
             
              zeebe:
         | 
| 21 | 
            -
                image: camunda/zeebe | 
| 21 | 
            +
                image: camunda/zeebe:${ZEEBE_VERSION:-0.26.1}
         | 
| 22 22 | 
             
                environment:
         | 
| 23 23 | 
             
                  ZEEBE_LOG_LEVEL: debug
         | 
| 24 24 | 
             
                volumes:
         | 
| @@ -26,7 +26,7 @@ services: | |
| 26 26 | 
             
                  - ./compose/application.yml:/usr/local/zeebe/config/application.yaml
         | 
| 27 27 |  | 
| 28 28 | 
             
              monitor:
         | 
| 29 | 
            -
                image: camunda/zeebe-simple-monitor:0.19. | 
| 29 | 
            +
                image: camunda/zeebe-simple-monitor:0.19.1
         | 
| 30 30 | 
             
                environment:
         | 
| 31 31 | 
             
                  - zeebe.client.broker.contactPoint=zeebe:26500
         | 
| 32 32 | 
             
                  - zeebe.client.worker.hazelcast.connection=zeebe:5701
         | 
    
        data/lib/zeebe_bpmn_rspec.rb
    CHANGED
    
    | @@ -1,14 +1,16 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require "active_support"
         | 
| 3 4 | 
             
            require "rspec"
         | 
| 4 5 | 
             
            require "zeebe/client"
         | 
| 5 6 | 
             
            require "zeebe_bpmn_rspec/helpers"
         | 
| 6 7 | 
             
            require "zeebe_bpmn_rspec/version"
         | 
| 8 | 
            +
            require "zeebe_bpmn_rspec/matchers/have_activated"
         | 
| 7 9 |  | 
| 8 10 | 
             
            # Top-level gem module
         | 
| 9 11 | 
             
            module ZeebeBpmnRspec
         | 
| 10 12 | 
             
              class << self
         | 
| 11 | 
            -
                attr_writer :client, :zeebe_address
         | 
| 13 | 
            +
                attr_writer :client, :zeebe_address, :activate_request_timeout
         | 
| 12 14 |  | 
| 13 15 | 
             
                def configure
         | 
| 14 16 | 
             
                  yield(self)
         | 
| @@ -23,6 +25,10 @@ module ZeebeBpmnRspec | |
| 23 25 | 
             
                def zeebe_address
         | 
| 24 26 | 
             
                  @zeebe_address || ENV["ZEEBE_ADDRESS"] || (raise "zeebe_address must be set")
         | 
| 25 27 | 
             
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def activate_request_timeout
         | 
| 30 | 
            +
                  @activate_request_timeout || 1000
         | 
| 31 | 
            +
                end
         | 
| 26 32 | 
             
              end
         | 
| 27 33 | 
             
            end
         | 
| 28 34 |  | 
| @@ -1,6 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require "active_support"
         | 
| 4 3 | 
             
            require "active_support/core_ext/hash/keys"
         | 
| 5 4 | 
             
            require "json"
         | 
| 6 5 |  | 
| @@ -8,27 +7,50 @@ module ZeebeBpmnRspec | |
| 8 7 | 
             
              class ActivatedJob
         | 
| 9 8 | 
             
                include ::Zeebe::Client::GatewayProtocol # for direct reference of request classes
         | 
| 10 9 |  | 
| 11 | 
            -
                attr_reader :job, :type | 
| 10 | 
            +
                attr_reader :job, :type
         | 
| 12 11 |  | 
| 13 | 
            -
                def initialize(job, type:, workflow_instance_key:, client:, context:)
         | 
| 12 | 
            +
                def initialize(job, type:, workflow_instance_key:, client:, context:, validate:) # rubocop:disable Metrics/ParameterLists
         | 
| 14 13 | 
             
                  @job = job
         | 
| 15 14 | 
             
                  @type = type
         | 
| 16 15 | 
             
                  @workflow_instance_key = workflow_instance_key
         | 
| 17 16 | 
             
                  @client = client
         | 
| 18 17 | 
             
                  @context = context
         | 
| 19 18 |  | 
| 20 | 
            -
                   | 
| 21 | 
            -
                     | 
| 22 | 
            -
                      expect(job | 
| 23 | 
            -
                       | 
| 19 | 
            +
                  if validate
         | 
| 20 | 
            +
                    context.instance_eval do
         | 
| 21 | 
            +
                      expect(job).not_to be_nil, "expected to receive job of type '#{type}' but received none"
         | 
| 22 | 
            +
                      aggregate_failures do
         | 
| 23 | 
            +
                        expect(job.workflowInstanceKey).to eq(workflow_instance_key)
         | 
| 24 | 
            +
                        expect(job.type).to eq(type)
         | 
| 25 | 
            +
                      end
         | 
| 24 26 | 
             
                    end
         | 
| 25 27 | 
             
                  end
         | 
| 26 28 | 
             
                end
         | 
| 27 29 |  | 
| 30 | 
            +
                def raw
         | 
| 31 | 
            +
                  job
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 28 34 | 
             
                def key
         | 
| 29 35 | 
             
                  job.key
         | 
| 30 36 | 
             
                end
         | 
| 31 37 |  | 
| 38 | 
            +
                def workflow_instance_key
         | 
| 39 | 
            +
                  job.workflowInstanceKey
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def retries
         | 
| 43 | 
            +
                  job.retries
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def task_key
         | 
| 47 | 
            +
                  job.elementInstanceKey
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def to_s
         | 
| 51 | 
            +
                  raw.to_s
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 32 54 | 
             
                def variables
         | 
| 33 55 | 
             
                  @_variables ||= JSON.parse(job.variables)
         | 
| 34 56 | 
             
                end
         | 
| @@ -87,6 +109,13 @@ module ZeebeBpmnRspec | |
| 87 109 | 
             
                end
         | 
| 88 110 | 
             
                alias complete and_complete
         | 
| 89 111 |  | 
| 112 | 
            +
                def update_retries(retries = 1)
         | 
| 113 | 
            +
                  client.update_job_retries(UpdateJobRetriesRequest.new(
         | 
| 114 | 
            +
                                              jobKey: job.key,
         | 
| 115 | 
            +
                                              retries: retries
         | 
| 116 | 
            +
                                            ))
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 90 119 | 
             
                private
         | 
| 91 120 |  | 
| 92 121 | 
             
                attr_reader :client, :context
         | 
| @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require "active_support/core_ext/object/blank"
         | 
| 3 4 | 
             
            require "zeebe_bpmn_rspec/activated_job"
         | 
| 4 5 |  | 
| 5 6 | 
             
            module ZeebeBpmnRspec
         | 
| @@ -26,7 +27,7 @@ module ZeebeBpmnRspec | |
| 26 27 | 
             
                                                                      variables: variables.to_json
         | 
| 27 28 | 
             
                                                                    ))
         | 
| 28 29 | 
             
                  @__workflow_instance_key = workflow.workflowInstanceKey
         | 
| 29 | 
            -
                  yield(workflow.workflowInstanceKey)
         | 
| 30 | 
            +
                  yield(workflow.workflowInstanceKey) if block_given?
         | 
| 30 31 | 
             
                rescue Exception => e # rubocop:disable Lint/RescueException
         | 
| 31 32 | 
             
                  # exceptions are rescued to ensure that instances are cancelled
         | 
| 32 33 | 
             
                  # any error is re-raised below
         | 
| @@ -64,37 +65,48 @@ module ZeebeBpmnRspec | |
| 64 65 | 
             
                  @__workflow_instance_key
         | 
| 65 66 | 
             
                end
         | 
| 66 67 |  | 
| 67 | 
            -
                def activate_job(type)
         | 
| 68 | 
            -
                   | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 68 | 
            +
                def activate_job(type, fetch_variables: nil, validate: true, worker: "#{type}-#{SecureRandom.hex}")
         | 
| 69 | 
            +
                  raise ArgumentError.new("'worker' cannot be blank") if worker.blank?
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  stream = _zeebe_client.activate_jobs(ActivateJobsRequest.new({
         | 
| 72 | 
            +
                    type: type,
         | 
| 73 | 
            +
                    worker: worker,
         | 
| 74 | 
            +
                    maxJobsToActivate: 1,
         | 
| 75 | 
            +
                    timeout: 1000,
         | 
| 76 | 
            +
                    fetchVariable: fetch_variables&.then { |v| Array(v) },
         | 
| 77 | 
            +
                    requestTimeout: ZeebeBpmnRspec.activate_request_timeout,
         | 
| 78 | 
            +
                  }.compact))
         | 
| 75 79 |  | 
| 76 80 | 
             
                  job = nil
         | 
| 77 81 | 
             
                  stream.find { |response| job = response.jobs.first }
         | 
| 78 | 
            -
                  raise "No job with type #{type.inspect} found" if job.nil?
         | 
| 79 | 
            -
             | 
| 80 82 | 
             
                  # puts job.inspect # support debug logging?
         | 
| 81 83 |  | 
| 82 84 | 
             
                  ActivatedJob.new(job,
         | 
| 83 85 | 
             
                                   type: type,
         | 
| 84 86 | 
             
                                   workflow_instance_key: workflow_instance_key,
         | 
| 85 87 | 
             
                                   client: _zeebe_client,
         | 
| 86 | 
            -
                                   context: self | 
| 88 | 
            +
                                   context: self,
         | 
| 89 | 
            +
                                   validate: validate)
         | 
| 87 90 | 
             
                end
         | 
| 88 91 | 
             
                alias process_job activate_job
         | 
| 89 92 | 
             
                # TODO: deprecate process_job
         | 
| 90 93 |  | 
| 91 | 
            -
                def  | 
| 94 | 
            +
                def job_with_type(type, fetch_variables: nil)
         | 
| 95 | 
            +
                  activate_job(type, fetch_variables: fetch_variables, validate: false)
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                def expect_job_of_type(type, fetch_variables: nil)
         | 
| 99 | 
            +
                  expect(job_with_type(type, fetch_variables: fetch_variables))
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                def activate_jobs(type, max_jobs: nil, fetch_variables: nil)
         | 
| 92 103 | 
             
                  stream = _zeebe_client.activate_jobs(ActivateJobsRequest.new({
         | 
| 93 104 | 
             
                    type: type,
         | 
| 94 105 | 
             
                    worker: "#{type}-#{SecureRandom.hex}",
         | 
| 95 106 | 
             
                    maxJobsToActivate: max_jobs,
         | 
| 96 | 
            -
                    timeout:  | 
| 97 | 
            -
                     | 
| 107 | 
            +
                    timeout: 1000,
         | 
| 108 | 
            +
                    fetchVariable: fetch_variables&.then { |v| Array(v) },
         | 
| 109 | 
            +
                    requestTimeout: ZeebeBpmnRspec.activate_request_timeout,
         | 
| 98 110 | 
             
                  }.compact))
         | 
| 99 111 |  | 
| 100 112 | 
             
                  Enumerator.new do |yielder|
         | 
| @@ -104,23 +116,32 @@ module ZeebeBpmnRspec | |
| 104 116 | 
             
                                                    type: type,
         | 
| 105 117 | 
             
                                                    workflow_instance_key: workflow_instance_key,
         | 
| 106 118 | 
             
                                                    client: _zeebe_client,
         | 
| 107 | 
            -
                                                    context: self | 
| 119 | 
            +
                                                    context: self,
         | 
| 120 | 
            +
                                                    validate: true)
         | 
| 108 121 | 
             
                      end
         | 
| 109 122 | 
             
                    end
         | 
| 110 123 | 
             
                  end
         | 
| 111 124 | 
             
                end
         | 
| 112 125 |  | 
| 113 | 
            -
                def publish_message(name, correlation_key:, variables: nil)
         | 
| 126 | 
            +
                def publish_message(name, correlation_key:, variables: nil, ttl_ms: 5000)
         | 
| 114 127 | 
             
                  _zeebe_client.publish_message(PublishMessageRequest.new(
         | 
| 115 128 | 
             
                                                  {
         | 
| 116 129 | 
             
                                                    name: name,
         | 
| 117 130 | 
             
                                                    correlationKey: correlation_key,
         | 
| 118 | 
            -
                                                    timeToLive:  | 
| 131 | 
            +
                                                    timeToLive: ttl_ms,
         | 
| 119 132 | 
             
                                                    variables: variables&.to_json,
         | 
| 120 133 | 
             
                                                  }.compact
         | 
| 121 134 | 
             
                                                ))
         | 
| 122 135 | 
             
                end
         | 
| 123 136 |  | 
| 137 | 
            +
                def set_variables(key, variables, local: true)
         | 
| 138 | 
            +
                  _zeebe_client.set_variables(SetVariablesRequest.new(
         | 
| 139 | 
            +
                                                elementInstanceKey: key,
         | 
| 140 | 
            +
                                                variables: variables.to_json,
         | 
| 141 | 
            +
                                                local: local
         | 
| 142 | 
            +
                                              ))
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
             | 
| 124 145 | 
             
                def reset_zeebe!
         | 
| 125 146 | 
             
                  @__workflow_instance_key = nil
         | 
| 126 147 | 
             
                end
         | 
| @@ -0,0 +1,99 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "zeebe_bpmn_rspec/matchers/have_variables"
         | 
| 4 | 
            +
            require "zeebe_bpmn_rspec/matchers/have_headers"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module ZeebeBpmnRspec
         | 
| 7 | 
            +
              class HaveActivatedMatcherError < StandardError
         | 
| 8 | 
            +
                def initialize
         | 
| 9 | 
            +
                  super("Only one of complete, fail, and throw error can be specified")
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            # rubocop:disable Metrics/BlockLength
         | 
| 15 | 
            +
            RSpec::Matchers.define :have_activated do
         | 
| 16 | 
            +
              match do |job|
         | 
| 17 | 
            +
                @job = job
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                @matcher_error = nil
         | 
| 20 | 
            +
                begin
         | 
| 21 | 
            +
                  aggregate_failures "activated job#{of_type(job)}" do
         | 
| 22 | 
            +
                    unless job.is_a?(ZeebeBpmnRspec::ActivatedJob)
         | 
| 23 | 
            +
                      raise ArgumentError.new("expectation target must be a "\
         | 
| 24 | 
            +
                                              "#{ZeebeBpmnRspec::ActivatedJob.name}, got #{job.inspect}")
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    if job.raw.nil?
         | 
| 28 | 
            +
                      raise RSpec::Expectations::ExpectationNotMetError.new("expected activated job#{of_type(job)}, got nil")
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    expect(job).to have_variables(@variables) if @variables
         | 
| 32 | 
            +
                    expect(job).to have_headers(@headers) if @headers
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                rescue Exception => e # rubocop:disable Lint/RescueException
         | 
| 35 | 
            +
                  @matcher_error = e
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                return false if @matcher_error
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                if @complete
         | 
| 40 | 
            +
                  job.complete(@output || {})
         | 
| 41 | 
            +
                elsif @fail
         | 
| 42 | 
            +
                  job.fail(@fail_message, retries: @retries)
         | 
| 43 | 
            +
                elsif @throw
         | 
| 44 | 
            +
                  job.throw_error(@error_code, @throw_message)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                true
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              def of_type(job)
         | 
| 51 | 
            +
                job.respond_to?(:type) ? " of type #{job.type}" : nil
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              failure_message do |_job|
         | 
| 55 | 
            +
                raise matcher_error
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              attr_reader :job, :matcher_error
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              def predestined?
         | 
| 61 | 
            +
                @complete || @fail || @throw
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              def check_predestined!
         | 
| 65 | 
            +
                raise ZeebeBpmnRspec::HaveActivatedMatcherError.new if predestined?
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              chain :with_variables do |variables|
         | 
| 69 | 
            +
                @variables = variables.is_a?(Hash) ? variables.stringify_keys : variables
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              chain :with_headers do |headers|
         | 
| 73 | 
            +
                @headers = headers.is_a?(Hash) ? headers.stringify_keys : headers
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              chain :and_complete do |output = nil|
         | 
| 77 | 
            +
                check_predestined!
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                @output = output
         | 
| 80 | 
            +
                @complete = true
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              chain :and_fail do |message = nil, retries: 0|
         | 
| 84 | 
            +
                check_predestined!
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                @fail_message = message
         | 
| 87 | 
            +
                @retries = retries
         | 
| 88 | 
            +
                @fail = true
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              chain :and_throw_error do |error_code, message = nil|
         | 
| 92 | 
            +
                check_predestined!
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                @error_code = error_code
         | 
| 95 | 
            +
                @throw_message = message
         | 
| 96 | 
            +
                @throw = true
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
            end
         | 
| 99 | 
            +
            # rubocop:enable Metrics/BlockLength
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec::Matchers.define :have_headers do
         | 
| 4 | 
            +
              match do |actual|
         | 
| 5 | 
            +
                @job = actual
         | 
| 6 | 
            +
                @actual = @job.headers
         | 
| 7 | 
            +
                values_match?(expected, @actual)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              failure_message do |_actual|
         | 
| 11 | 
            +
                "expected that job:\n  #{@job}\n\nwould have headers #{expected}"
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              diffable
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec::Matchers.define :have_variables do |expected|
         | 
| 4 | 
            +
              match do |actual|
         | 
| 5 | 
            +
                @job = actual
         | 
| 6 | 
            +
                @actual = @job.variables
         | 
| 7 | 
            +
                values_match?(expected, @actual)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              failure_message do |_actual|
         | 
| 11 | 
            +
                "expected that job:\n  #{@job}\n\nwould have variables #{expected}"
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              diffable
         | 
| 15 | 
            +
            end
         | 
    
        data/zeebe_bpmn_rspec.gemspec
    CHANGED
    
    | @@ -41,7 +41,9 @@ Gem::Specification.new do |spec| | |
| 41 41 | 
             
              spec.executables   = []
         | 
| 42 42 | 
             
              spec.require_paths = ["lib"]
         | 
| 43 43 |  | 
| 44 | 
            -
              spec. | 
| 44 | 
            +
              spec.required_ruby_version = ">= 2.6"
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              spec.add_development_dependency "bundler", "~> 2.1"
         | 
| 45 47 | 
             
              spec.add_development_dependency "ezcater_rubocop", "2.0.0"
         | 
| 46 48 | 
             
              spec.add_development_dependency "overcommit"
         | 
| 47 49 | 
             
              spec.add_development_dependency "rake", "~> 10.0"
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: zeebe_bpmn_rspec
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.5.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - ezCater, Inc
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-05-27 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -16,14 +16,14 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - "~>"
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: '1 | 
| 19 | 
            +
                    version: '2.1'
         | 
| 20 20 | 
             
              type: :development
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - "~>"
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: '1 | 
| 26 | 
            +
                    version: '2.1'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: ezcater_rubocop
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -152,6 +152,9 @@ files: | |
| 152 152 | 
             
            - lib/zeebe_bpmn_rspec.rb
         | 
| 153 153 | 
             
            - lib/zeebe_bpmn_rspec/activated_job.rb
         | 
| 154 154 | 
             
            - lib/zeebe_bpmn_rspec/helpers.rb
         | 
| 155 | 
            +
            - lib/zeebe_bpmn_rspec/matchers/have_activated.rb
         | 
| 156 | 
            +
            - lib/zeebe_bpmn_rspec/matchers/have_headers.rb
         | 
| 157 | 
            +
            - lib/zeebe_bpmn_rspec/matchers/have_variables.rb
         | 
| 155 158 | 
             
            - lib/zeebe_bpmn_rspec/version.rb
         | 
| 156 159 | 
             
            - zeebe_bpmn_rspec.gemspec
         | 
| 157 160 | 
             
            homepage: https://github.com/ezcater/zeebe_bpmn_rspec
         | 
| @@ -167,14 +170,14 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 167 170 | 
             
              requirements:
         | 
| 168 171 | 
             
              - - ">="
         | 
| 169 172 | 
             
                - !ruby/object:Gem::Version
         | 
| 170 | 
            -
                  version: ' | 
| 173 | 
            +
                  version: '2.6'
         | 
| 171 174 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 172 175 | 
             
              requirements:
         | 
| 173 176 | 
             
              - - ">="
         | 
| 174 177 | 
             
                - !ruby/object:Gem::Version
         | 
| 175 178 | 
             
                  version: '0'
         | 
| 176 179 | 
             
            requirements: []
         | 
| 177 | 
            -
            rubygems_version: 3. | 
| 180 | 
            +
            rubygems_version: 3.1.4
         | 
| 178 181 | 
             
            signing_key:
         | 
| 179 182 | 
             
            specification_version: 4
         | 
| 180 183 | 
             
            summary: Zeebe BPMN testing using RSpec
         |