prontoforms 0.2.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7c768e20e9e5d22ed71d1670d805adf5aea683eda22749b414813fd7db7e072
4
- data.tar.gz: 41ce8c58c17c213b2836109cb6f61d122453c70e848004c6c554ebd129fca3f5
3
+ metadata.gz: f254afead3ca132b09b3e4ebf60cd559326bce2e0c858bc718fd1211fc7f4db2
4
+ data.tar.gz: ff60c3483da8612616398ab4cab00f818e7447746ee6b34c712b612031d1f8f6
5
5
  SHA512:
6
- metadata.gz: 900424f174118c59d4fc7879d60f062054fca5dbc5d7404a047e9737b872ed3db69d2f1eb8cff3d23770e317ada5ea0014295c46c30201e84a29b64086040523
7
- data.tar.gz: 2c46e843c469f31915e19b54193804890ab88d9d4632127e84c39895587e157561917cedd35a1a927d6cd25522692675f3a4606a7e23d85301aca3c81ed269bc
6
+ metadata.gz: dee8fa61c40fc5a1ba90e7ca95c9b49d5c8e88df0221e0d27bddff417c1554ac424d4ee2cf388ee58bfc01e6b688174f1b04bb478a84a24a27bfe9677e58f85f
7
+ data.tar.gz: 3ee0a6c9ca3da3652000194106ae0b6f29d10a617c292ae114a9ccf9e6f9deef591cd9a6e9d16e4220a444900aeffb81555a35eae7bdfa178dc1c5b45168a819
@@ -0,0 +1,66 @@
1
+ name: Checks
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+
7
+ jobs:
8
+ test:
9
+ name: Run automated tests
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout repository
13
+ uses: actions/checkout@v2
14
+
15
+ - name: Set up ruby
16
+ uses: actions/setup-ruby@v1
17
+ with:
18
+ ruby-version: 2.6
19
+
20
+ - name: Install dependencies
21
+ run: |
22
+ gem install bundler -v 2.1.4
23
+ bundle install
24
+
25
+ - name: Test
26
+ run: bundle exec rake
27
+
28
+ - name: Report test coverage
29
+ uses: paambaati/codeclimate-action@v2.7.4
30
+ env:
31
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
32
+
33
+ rubocop:
34
+ name: Rubocop
35
+ runs-on: ubuntu-latest
36
+ strategy:
37
+ fail-fast: false
38
+
39
+ steps:
40
+ - name: Checkout repository
41
+ uses: actions/checkout@v2
42
+
43
+ - name: Set up Ruby
44
+ uses: ruby/setup-ruby@v1
45
+ with:
46
+ ruby-version: 2.6
47
+
48
+ - name: Install Code Scanning integration
49
+ run: bundle add code-scanning-rubocop --version 0.3.0 --skip-install
50
+
51
+ - name: Install dependencies
52
+ run: |
53
+ gem install bundler -v 2.1.4
54
+ bundle install
55
+
56
+ - name: Rubocop run
57
+ run: |
58
+ bash -c "
59
+ bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
60
+ [[ $? -ne 2 ]]
61
+ "
62
+
63
+ - name: Upload Sarif output
64
+ uses: github/codeql-action/upload-sarif@v1
65
+ with:
66
+ sarif_file: rubocop.sarif
data/.gitignore CHANGED
@@ -11,3 +11,5 @@ Gemfile.lock
11
11
 
12
12
  # rspec failure tracking
13
13
  .rspec_status
14
+
15
+ **/.DS_Store
@@ -0,0 +1,12 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ NewCops: enable
4
+
5
+ Style/ClassAndModuleChildren:
6
+ Enabled: false
7
+
8
+ Style/StringLiterals:
9
+ EnforcedStyle: single_quotes
10
+
11
+ Layout/FirstHashElementIndentation:
12
+ Enabled: false
@@ -1,6 +1,16 @@
1
1
  ---
2
+ os: linux
3
+ dist: xenial
2
4
  language: ruby
3
5
  cache: bundler
4
6
  rvm:
5
7
  - 2.6.0
6
8
  before_install: gem install bundler -v 2.1.4
9
+ before_script:
10
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
11
+ - chmod +x ./cc-test-reporter
12
+ - ./cc-test-reporter before-build
13
+ script:
14
+ - bundle exec rspec
15
+ after_script:
16
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -0,0 +1,31 @@
1
+ # prontoforms changelog
2
+
3
+ ## [Unreleased]
4
+ ### Added
5
+ * Added Form resource
6
+ * Can retrieve forms by form space
7
+
8
+ ## [v0.3.1] - 15 Sep 2020
9
+ ### Removed
10
+ * Unused `InvalidHttpVerb` error class
11
+
12
+ ## [v0.3.0] - 15 Sep 2020
13
+ ### Added
14
+ * Autogenerated documentation via YARD.
15
+
16
+ ### Changed
17
+ * Errors now provide a message describing the issue
18
+ * `ProntoForms::Client` now raises error on invalid resource definition.
19
+
20
+ ## [v0.2.0] - 26 Aug 2020
21
+ ### Bugfixes
22
+ * Corrected pagination of resource lists
23
+
24
+ ## [v0.1.0] - 25 Aug 2020
25
+ * Initial release
26
+
27
+ [Unreleased]: https://github.com/paulholden2/prontoforms/compare/v0.3.1...HEAD
28
+ [v0.1.0]: https://github.com/paulholden2/prontoforms/releases/tag/v0.1.0
29
+ [v0.2.0]: https://github.com/paulholden2/prontoforms/releases/tag/v0.2.0
30
+ [v0.3.0]: https://github.com/paulholden2/prontoforms/releases/tag/v0.3.0
31
+ [v0.3.1]: https://github.com/paulholden2/prontoforms/releases/tag/v0.3.1
data/Gemfile CHANGED
@@ -1,4 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in prontoforms.gemspec
4
6
  gemspec
7
+
8
+ group :development, :test do
9
+ gem 'simplecov', '~> 0.17.1'
10
+ end
data/README.md CHANGED
@@ -1,7 +1,12 @@
1
1
  # ProntoForms
2
2
 
3
+ [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fpaulholden2%2Fprontoforms%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/paulholden2/prontoforms/goto?ref=master) [![Gem Version](https://badge.fury.io/rb/prontoforms.svg)](https://badge.fury.io/rb/prontoforms) [![Inline docs](http://inch-ci.org/github/paulholden2/prontoforms.svg?branch=master)](http://inch-ci.org/github/paulholden2/prontoforms) [![Maintainability](https://api.codeclimate.com/v1/badges/e47cd40058313e1c1c38/maintainability)](https://codeclimate.com/github/paulholden2/prontoforms/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/e47cd40058313e1c1c38/test_coverage)](https://codeclimate.com/github/paulholden2/prontoforms/test_coverage)
4
+
3
5
  A library for interacting with the ProntoForms REST API in Ruby applications.
4
6
 
7
+ Note: version 0.4.0 included a breaking change, and has been yanked from
8
+ RubyGems. If you are using it, please upgrade to 1.x or revert to 0.3.1.
9
+
5
10
  ## Installation
6
11
 
7
12
  Add this line to your application's Gemfile:
@@ -20,7 +25,16 @@ Or install it yourself as:
20
25
 
21
26
  ## Usage
22
27
 
23
- Check back later
28
+ To get started, first [create a ProntoForms API key] in your ProntoForms
29
+ account. Then you can begin using the API client in your Ruby application:
30
+
31
+ ```rb
32
+ client = ProntoForms::Client.new(api_key_id, api_key_secret)
33
+ client.form_spaces # Returns all FormSpaces in your account
34
+ ```
35
+
36
+ Review [the documentation](https://rubydoc.info/github/paulholden2/prontoforms)
37
+ for more information on how to use this library to interact with ProntoForms.
24
38
 
25
39
  ## Development
26
40
 
@@ -37,3 +51,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/paulho
37
51
  ## License
38
52
 
39
53
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
54
+
55
+ [create a ProntoForms API key]: https://support.prontoforms.com/hc/en-us/articles/217496468-Setup-an-API-Application-on-ProntoForms#Create
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -1,14 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "prontoforms"
4
+ require 'bundler/setup'
5
+ require 'prontoforms'
6
+ require 'irb'
5
7
 
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
8
  IRB.start(__FILE__)
data/bin/setup CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env bash
2
+ # frozen_string_literal: true
3
+
2
4
  set -euo pipefail
3
5
  IFS=$'\n\t'
4
6
  set -vx
5
7
 
6
8
  bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,6 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'prontoforms/version'
2
4
  require 'prontoforms/client'
3
5
 
4
6
  module ProntoForms
5
- class Error < StandardError; end
7
+ # Base error class.
8
+ class Error < StandardError
9
+ attr_reader :message
10
+
11
+ def initialize(message)
12
+ @message = message
13
+ end
14
+ end
6
15
  end
@@ -1,43 +1,102 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'json'
3
5
  require 'prontoforms/resource_list'
4
6
  require 'prontoforms/form_space'
5
7
  require 'prontoforms/form_submission'
8
+ require 'prontoforms/user'
6
9
 
7
10
  module ProntoForms
11
+ # Allows you to retrieve resources from ProntoForms and perform other
12
+ # functions with the API.
8
13
  class Client
9
- attr_reader :api_key_id, :api_key_secret
14
+ # @return [String] ProntoForms API key ID
15
+ attr_reader :api_key_id
16
+ # @return [String] ProntoForms API key secret
17
+ attr_reader :api_key_secret
10
18
 
19
+ # Create a client and use provided API credentials
20
+ # @param api_key_id Your ProntoForms REST API key
21
+ # @param api_key_secret Your ProntoForms REST API secret
11
22
  def initialize(api_key_id, api_key_secret)
12
23
  @api_key_id = api_key_id
13
24
  @api_key_secret = api_key_secret
14
25
  end
15
26
 
16
- def self.resource(method, verb: :get, resource:, url: resource.resource_name)
17
- # TODO: Raise error if verb is invalid
18
-
27
+ # Defines a resource that can be retrieved in a list
28
+ # @return [nil]
29
+ # @api private
30
+ # @!macro [attach] resource_list
31
+ # @method $1
32
+ # Retrieve a list of $2 resources
33
+ # @return [ResourceList] A ResourceList containing $2 results
34
+ def self.resource_list(method, resource, url = resource.resource_name)
19
35
  define_method(method) do |query: {}|
20
- res = connection.send(verb) do |req|
36
+ res = connection.get do |req|
21
37
  req.url url
22
38
  query.each { |k, v| req.params[k] = v }
23
39
  end
24
- if res.success?
25
- ResourceList.new(JSON.parse(res.body), {
26
- 'p' => 0,
27
- 's' => 100
28
- }.merge(query), method, resource, self)
29
- else
30
- nil
31
- end
40
+
41
+ data = JSON.parse(res.body)
42
+
43
+ return nil if data.fetch('pageData').size.zero?
44
+
45
+ ResourceList.new(data, { 'p' => 0, 's' => 100 }.merge(query), method,
46
+ resource, self)
32
47
  end
33
48
  end
34
49
 
35
- resource :form_spaces, resource: FormSpace
36
- resource :form_submissions, resource: FormSubmission
50
+ resource_list :form_spaces, FormSpace
51
+ resource_list :form_submissions, FormSubmission
52
+
53
+ # Retrieve a user by identifier
54
+ # @param id [String] The user identifier
55
+ # @return [User] A User object for the requested user
56
+ def user(id)
57
+ raise ArgumentError, 'id must be provided' if id.nil?
58
+
59
+ res = connection.get do |req|
60
+ req.url "users/#{id}"
61
+ end
62
+
63
+ User.new(JSON.parse(res.body), self)
64
+ end
65
+
66
+ # Retrieve a form space by its identifier
67
+ # @param id [String] The form space identifier
68
+ # @return [FormSpace] A FormSpace object
69
+ def form_space(id)
70
+ raise ArgumentError, 'id must be provided' if id.nil?
71
+
72
+ res = connection.get do |req|
73
+ req.url "formspaces/#{id}"
74
+ end
75
+
76
+ FormSpace.new(JSON.parse(res.body), self)
77
+ end
78
+
79
+ # Retrieve a form submission by identifier
80
+ # @param id [String] The form submission identifier
81
+ # @return [FormSubmission] A FormSubmission object
82
+ def form_submission(id)
83
+ return nil if id.nil?
84
+
85
+ res = connection.get do |req|
86
+ req.url "data/#{id}"
87
+ end
88
+
89
+ FormSubmission.new(JSON.parse(res.body), self)
90
+ end
37
91
 
92
+ # Create a connection that can be used to execute a request against the
93
+ # ProntoForms API.
94
+ # @return [Faraday::Connection]
95
+ # @api private
38
96
  def connection
39
97
  Faraday.new(url: 'https://api.prontoforms.com/api/1.1') do |conn|
40
98
  conn.basic_auth(api_key_id, api_key_secret)
99
+ conn.use Faraday::Response::RaiseError
41
100
  end
42
101
  end
43
102
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'prontoforms/resource'
4
+
5
+ module ProntoForms
6
+ # A Document is a configuration that generates output data or files when
7
+ # attached to a form.
8
+ class Document < Resource
9
+ def self.resource_name
10
+ 'documents'
11
+ end
12
+
13
+ # @return [String] The Document identifier
14
+ property :id, key: 'identifier'
15
+ # @return [String] Document type
16
+ property :type, key: 'type'
17
+ # @return [String] Document name
18
+ property :name, key: 'name'
19
+ # @return [String] Document descriptiojn
20
+ property :description, key: 'description'
21
+ # @return [String] Document form version
22
+ property :form_document_version, key: 'formDocumentVersion'
23
+ # @return [Boolean] Whether the document is standard (system generated)
24
+ property :standard, key: 'standard'
25
+ # @return [String] Whether the document auto-links to new forms
26
+ property :auto_link, key: 'autoLink'
27
+
28
+ alias standard? standard
29
+ alias auto_link? auto_link
30
+ end
31
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'prontoforms/resource'
4
+ require 'prontoforms/form_iteration'
5
+
6
+ module ProntoForms
7
+ # A form includes inputs, validations, logic, and other configuration that
8
+ # facilitates data capture for a specific purpose.
9
+ class Form < Resource
10
+ def self.resource_name
11
+ 'forms'
12
+ end
13
+
14
+ # @return [String] The Form identifier
15
+ property :id, key: 'identifier'
16
+ # @return [String] Form name
17
+ property :name, key: 'name'
18
+ # @return [String] Form description
19
+ property :description, key: 'description'
20
+ # @return [String] Form state
21
+ property :state, key: 'state'
22
+
23
+ # Get the Form's form space ID
24
+ # @return [String] Form space identifier
25
+ def form_space_id
26
+ parent.id
27
+ end
28
+
29
+ def active_version_id
30
+ full_data.dig('activeVersion', 'identifier')
31
+ end
32
+
33
+ def current_version
34
+ res = client.connection.get do |req|
35
+ req.url "#{url}/iterations/#{active_version_id}"
36
+ end
37
+
38
+ FormIteration.new(JSON.parse(res.body), client, self)
39
+ end
40
+
41
+ def iteration(id)
42
+ raise ArgumentError, 'id must be provided' if id.nil?
43
+
44
+ res = client.connection.get do |req|
45
+ req.url "#{url}/iterations/#{id}"
46
+ end
47
+
48
+ FormIteration.new(JSON.parse(res.body), client, self)
49
+ end
50
+
51
+ def iterations(query: {})
52
+ res = client.connection.get do |req|
53
+ req.url "#{url}/iterations"
54
+ end
55
+
56
+ ResourceList.new(JSON.parse(res.body), {
57
+ 'p' => 0,
58
+ 's' => 100
59
+ }.merge(query), :iterations, FormIteration, client, self)
60
+ end
61
+
62
+ private
63
+
64
+ def full_data
65
+ return @full_data unless @full_data.nil?
66
+
67
+ @full_data = client.form_space(form_space_id).form(id).data
68
+ @full_data
69
+ end
70
+
71
+ def url
72
+ "formspaces/#{form_space_id}/forms/#{id}"
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'prontoforms/resource'
4
+
5
+ module ProntoForms
6
+ # A form iteration is a form configuration, distinct from a form version
7
+ # in that version numbers increment when a form iteration is deployed.
8
+ class FormIteration < Resource
9
+ def self.resource_name
10
+ 'iterations'
11
+ end
12
+
13
+ # @return [String] The form iteration identifier
14
+ property :id, key: 'identifier'
15
+ # @return [Integer] Version number
16
+ property :version, key: 'version'
17
+ # @return [String] Form iteration state
18
+ property :state, key: 'state'
19
+ # @return [String] Initiation method for the form iteration
20
+ property :initiation_method, key: 'initiationMethod'
21
+ # @return [String] Can dispatched forms of this iteration be declined
22
+ property :dispatched_declinable, key: 'dispatchDeclinable'
23
+
24
+ alias can_decline_dispatch? dispatched_declinable
25
+
26
+ # @return [Array] Array of document IDs attached to this iteration
27
+ def document_ids
28
+ full_data.fetch('documentIds')
29
+ end
30
+
31
+ private
32
+
33
+ def full_data
34
+ return @full_data unless @full_data.nil?
35
+
36
+ @full_data = parent.iteration(id).data
37
+ @full_data
38
+ end
39
+ end
40
+ end
@@ -1,10 +1,65 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'prontoforms/resource'
4
+ require 'prontoforms/form'
5
+ require 'prontoforms/document'
2
6
 
3
7
  module ProntoForms
8
+ # Represents a form space resource in ProntoForms. Form spaces are the
9
+ # primary organizational unit for forms, data sources, destinations, and
10
+ # other resources.
4
11
  class FormSpace < Resource
12
+ # @return [String] The FormSpace identifier
5
13
  property :id, key: 'identifier'
14
+ # @return [String] The FormSpace name
6
15
  property :name, key: 'name'
16
+ # @return [String] The address that error emails are sent to
7
17
  property :problem_contact_email, key: 'problemContactEmail'
18
+ # @return [Boolean] Whether updates are automatically pushed to devices
8
19
  property :push_updates_to_device, key: 'pushUpdatesToDevice'
20
+
21
+ # Get all documents in the form space
22
+ # @return [ResourceList] A ResourceList containing Document objects
23
+ def documents
24
+ res = client.connection.get do |req|
25
+ req.url "formspaces/#{id}/documents"
26
+ end
27
+
28
+ ResourceList.new(JSON.parse(res.body), {
29
+ 'p' => 0,
30
+ 's' => 100
31
+ }, :documents, Document, self)
32
+ end
33
+
34
+ def document(document_id)
35
+ res = client.connection.get do |req|
36
+ req.url "formspaces/#{id}/documents/#{document_id}"
37
+ end
38
+
39
+ Document.new(JSON.parse(res.body), client, self)
40
+ end
41
+
42
+ def form(form_id)
43
+ res = client.connection.get do |req|
44
+ req.url "formspaces/#{id}/forms/#{form_id}"
45
+ end
46
+
47
+ data = JSON.parse(res.body)
48
+ Form.new(data, client, self)
49
+ end
50
+
51
+ # Get all forms in the form space
52
+ # @return [ResourceList] A ResourceList containing Form objects
53
+ def forms(query: {})
54
+ res = client.connection.get do |req|
55
+ req.url "formspaces/#{id}/forms"
56
+ query.each { |k, v| req.params[k] = v }
57
+ end
58
+
59
+ ResourceList.new(JSON.parse(res.body), {
60
+ 'p' => 0,
61
+ 's' => 100
62
+ }.merge(query), :forms, Form, client, self)
63
+ end
9
64
  end
10
65
  end
@@ -1,36 +1,137 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'prontoforms/resource'
3
5
 
4
6
  module ProntoForms
7
+ # A FormSubmission represents submitted form data in ProntoForms. It
8
+ # includes various metadata about the submission as well.
5
9
  class FormSubmission < Resource
6
- def self.resource_name() 'data'; end
10
+ def self.resource_name
11
+ 'data'
12
+ end
7
13
 
14
+ # @return [String] The FormSubmission identifier
8
15
  property :id, key: 'identifier'
16
+ # @return [String] Submission reference number
9
17
  property :reference_number, key: 'referenceNumber'
18
+ # @return [String] Submission state. One of: Complete, Processing,
19
+ # Dispatched
10
20
  property :state, key: 'state'
21
+ # @return [String] Submission data state
11
22
  property :data_state, key: 'dataState'
23
+ # @return [Boolean] Has the submission data been persisted on the server
12
24
  property :data_persisted, key: 'dataPersisted'
25
+ # @return [String] The form's version identifier
13
26
  property :form_version_id, key: 'formVersionId'
27
+ # @return [String] The form's identifier
14
28
  property :form_id, key: 'formId'
29
+ # @return [String] Submitter's user identifier
15
30
  property :user_id, key: 'userId'
31
+ # @return [String] Submitter's username
16
32
  property :username, key: 'username'
17
- # Aliases
18
- property :data_persisted?, key: 'dataPersisted'
19
- property :submitter_id, key: 'userId'
20
- property :submitter_username, key: 'username'
21
33
 
34
+ alias data_persisted? data_persisted
35
+ alias submitter_id user_id
36
+ alias submitter_username username
37
+
38
+ # @return [DateTime] Timestamp the submission was received by the server
22
39
  property :server_receive_date do
23
40
  str = data.fetch('serverReceiveDate')
24
41
  str.nil? ? nil : DateTime.strptime(str)
25
42
  end
26
43
 
44
+ # Retrieve the pages containing the form questions and answers
45
+ # @return [Hash] Hash of questions and answers for the FormSubmission
27
46
  def pages
47
+ document.fetch('pages')
48
+ end
49
+
50
+ # Retrieve the dispatching User, if the form was dispatched
51
+ # @return [User] The user that dispatched the form, or nil
52
+ def dispatcher
53
+ return nil unless dispatched?
54
+
55
+ client.user(document.dig('dispatcher', 'identifier'))
56
+ end
57
+
58
+ # Check if the form was dispatched
59
+ # @return [Boolean] True if the form was dispatched; false otherwise
60
+ def dispatched?
61
+ !document.dig('dispatcher', 'identifier').nil?
62
+ end
63
+
64
+ # Retrieve the form space for the form submission
65
+ # @return [FormSpace] Form space for the submission's form
66
+ def form_space
67
+ client.form_space(full_data.dig('form', 'formSpaceId'))
68
+ end
69
+
70
+ # Retrieve the form for the form submission
71
+ # @return [Form] Form for the submission
72
+ def form
73
+ form_space.form(full_data.dig('form', 'formId'))
74
+ end
75
+
76
+ # Retrieve the current version of the form
77
+ # @return [FormIteration] The form iteration
78
+ def form_version
79
+ form.current_version
80
+ end
81
+
82
+ # Retrieve all documents attached to this form submission
83
+ # @return [Array] Documents attached to the form submission
84
+ def documents(populate: false)
85
+ ids = form_version.document_ids
86
+ if populate
87
+ ids.map { |id| form_space.document(id) }
88
+ else
89
+ ids
90
+ end
91
+ end
92
+
93
+ # Download a specific document. The Document must have been attached to
94
+ # the form's current version at the time of submission.
95
+ # @return [IO] Data stream for the document
96
+ def download_document(document)
97
+ io = StringIO.new
98
+ client.connection.get do |req|
99
+ req.url "#{url}/documents/#{document.id}"
100
+ req.options.on_data = proc { |chunk| io << chunk }
101
+ end
102
+ io.rewind
103
+ io
104
+ end
105
+
106
+ private
107
+
108
+ def url
109
+ "#{resource_name}/#{id}"
110
+ end
111
+
112
+ def full_data
113
+ return @full_data unless @full_data.nil?
114
+
115
+ @full_data = client.form_submission(id).data
116
+ @full_data
117
+ end
118
+
119
+ # Returns additional data about the submission. Uses cached data,
120
+ # otherwise it loads and returns the data via #document!
121
+ def document
122
+ return @document unless @document.nil?
123
+
124
+ document!
125
+ end
126
+
127
+ # Force loads the submission document
128
+ def document!
28
129
  res = client.connection.get do |req|
29
130
  req.url "#{resource_name}/#{id}/document.json"
30
131
  end
31
- if res.success?
32
- JSON.parse(res.body).fetch('pages')
33
- end
132
+
133
+ @document = JSON.parse(res.body)
134
+ @document
34
135
  end
35
136
  end
36
137
  end
@@ -1,19 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  module ProntoForms
6
+ # Base class for resource-related classes.
4
7
  class Resource
5
- attr_reader :data, :client, :parent
8
+ # @return [Hash] Retrieve raw JSON data associated with this resource
9
+ attr_reader :data
10
+ # @return [Client] API client
11
+ attr_reader :client
12
+ # @return [Resource] Parent object (applicable to child resources)
13
+ attr_reader :parent
6
14
 
15
+ # Defines a property of the resource
16
+ # @return [nil]
17
+ # @api private
7
18
  def self.property(name, key: nil, &block)
8
- define_method(name) {
19
+ define_method(name) do
9
20
  if block_given?
10
21
  instance_eval(&block)
11
22
  elsif !key.nil?
12
- data.fetch(key)
13
- else
14
- nil
23
+ key = [key] unless key.is_a?(Array)
24
+ key.inject(data) { |obj, k| obj.fetch(k) }
15
25
  end
16
- }
26
+ end
17
27
  end
18
28
 
19
29
  def initialize(data, client, parent = nil)
@@ -22,11 +32,13 @@ module ProntoForms
22
32
  @parent = parent
23
33
  end
24
34
 
35
+ # The resource's identifier
25
36
  def self.resource_name
26
- name = self.to_s.split("::").last
37
+ name = to_s.split('::').last
27
38
  "#{name.downcase}s"
28
39
  end
29
40
 
41
+ # The resource's identifier
30
42
  def resource_name
31
43
  self.class.resource_name
32
44
  end
@@ -1,24 +1,46 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'prontoforms/resource'
2
4
 
3
5
  module ProntoForms
6
+ # A wrapper for retrieving paged resources.
4
7
  class ResourceList < Resource
5
- attr_reader :query, :method, :resource, :client, :parent
8
+ # @return [Hash] Query parameters for this resource list for e.g. filters
9
+ attr_reader :query
10
+ # @return [Symbol] Method to send to parent object (usually the client)
11
+ attr_reader :method
12
+ # @return [Class] Resource class
13
+ attr_reader :resource
14
+ # @return [Client] API client
15
+ attr_reader :client
16
+ # @return [Resource] Parent object (for child resources)
17
+ attr_reader :parent
6
18
 
19
+ # Initialize the resource list
20
+ # TODO: splat
21
+ # rubocop:disable Metrics/ParameterLists
7
22
  def initialize(data, query, method, resource, client, parent = nil)
8
23
  super(data, client)
9
24
  @query = query
10
25
  @method = method
11
26
  @resource = resource
27
+ @parent = parent
12
28
  end
29
+ # rubocop:enable Metrics/ParameterLists
13
30
 
31
+ # Retrieve the next page of results, using the same number of items per
32
+ # page as the original request.
33
+ # @return [ResourceList] A ResourceList with the next set of results
14
34
  def next
15
- client.send(method, query: query.merge({ 'p' => query['p'] + 1}))
35
+ client.send(method, query: query.merge({ 'p' => query['p'] + 1 }))
16
36
  end
17
37
 
38
+ # Retrieve the result set
39
+ # @return [Array] Array of resource objects
18
40
  def items
19
- @data.fetch('pageData').map { |item|
41
+ @data.fetch('pageData').map do |item|
20
42
  resource.new(item, client, parent)
21
- }
43
+ end
22
44
  end
23
45
  end
24
46
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'prontoforms/resource'
4
+
5
+ module ProntoForms
6
+ # A ProntoForms user account.
7
+ class User < Resource
8
+ def self.resource_name
9
+ 'users'
10
+ end
11
+
12
+ # @return [String] The User identifier
13
+ property :id, key: 'identifier'
14
+ # @return [String] The user's username
15
+ property :username, key: 'username'
16
+ # @return [String] The user's role
17
+ property :role, key: 'role'
18
+ # @return [String] The user's email address
19
+ property :email, key: 'email'
20
+ # @return [String] The user's first name
21
+ property :first_name, key: 'firstName'
22
+ # @return [String] The user's last name
23
+ property :last_name, key: 'lastName'
24
+ # @return [String] The user's preferred locale
25
+ property :locale, key: 'locale'
26
+
27
+ # Get a display name consisting of the first name followed by last name
28
+ # e.g. "John Doe"
29
+ # @return [String] The display name for the user
30
+ def display_name
31
+ "#{first_name} #{last_name}"
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ProntoForms
2
- VERSION = '0.2.0'
4
+ VERSION = '2.0.1'
3
5
  end
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'lib/prontoforms/version'
2
4
 
5
+ # rubocop:disable Layout/LineLength
3
6
  Gem::Specification.new do |spec|
4
- spec.name = 'prontoforms'
5
- spec.version = ProntoForms::VERSION
6
- spec.authors = ['Paul Holden']
7
- spec.email = ['paul@holdensoftware.com']
7
+ spec.name = 'prontoforms'
8
+ spec.version = ProntoForms::VERSION
9
+ spec.authors = ['Paul Holden']
10
+ spec.email = ['paul@codelunker.com']
8
11
 
9
- spec.summary = 'A library for using the ProntoForms REST API in Ruby applications.'
10
- spec.description = 'A library for using the ProntoForms REST API in Ruby applications.'
11
- spec.homepage = 'https://github.com/paulholden2/prontoforms'
12
- spec.license = 'MIT'
13
- spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
12
+ spec.summary = 'A library for using the ProntoForms REST API in Ruby applications.'
13
+ spec.description = 'A library for using the ProntoForms REST API in Ruby applications.'
14
+ spec.homepage = 'https://github.com/paulholden2/prontoforms'
15
+ spec.license = 'MIT'
16
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
14
17
 
15
18
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
16
19
 
@@ -19,17 +22,27 @@ Gem::Specification.new do |spec|
19
22
  spec.metadata['changelog_uri'] = 'https://github.com/paulholden2/prontoforms/blog/master/CHANGELOG.md'
20
23
 
21
24
  # Specify which files should be added to the gem when it is released.
22
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added
26
+ # into git.
27
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
28
+ `git ls-files -z`.split("\x0").reject do |f|
29
+ f.match(%r{^(test|spec|features)/})
30
+ end
25
31
  end
26
- spec.bindir = 'exe'
27
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+
33
+ spec.bindir = 'exe'
34
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
35
  spec.require_paths = ['lib']
29
36
 
30
37
  spec.add_dependency 'faraday', '~> 1.0'
31
38
 
32
39
  spec.add_development_dependency 'bundler', '~> 2.0'
33
- spec.add_development_dependency 'rake', '~> 10.0'
40
+ spec.add_development_dependency 'rake', '>= 12.3.3'
34
41
  spec.add_development_dependency 'rspec', '~> 3.0'
42
+ spec.add_development_dependency 'rubocop', '~> 0.82.0'
43
+ spec.add_development_dependency 'sinatra', '~> 2.0'
44
+ spec.add_development_dependency 'sinatra-contrib', '~> 2.0'
45
+ spec.add_development_dependency 'webmock', '~> 3.6'
46
+ spec.add_development_dependency 'yard', '~> 0.9'
35
47
  end
48
+ # rubocop:enable Layout/LineLength
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prontoforms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Holden
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-26 00:00:00.000000000 Z
11
+ date: 2020-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: 12.3.3
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: 12.3.3
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,15 +66,87 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.82.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.82.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: sinatra
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sinatra-contrib
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.6'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.6'
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.9'
69
139
  description: A library for using the ProntoForms REST API in Ruby applications.
70
140
  email:
71
- - paul@holdensoftware.com
141
+ - paul@codelunker.com
72
142
  executables: []
73
143
  extensions: []
74
144
  extra_rdoc_files: []
75
145
  files:
146
+ - ".github/workflows/checks.yml"
76
147
  - ".gitignore"
77
148
  - ".rspec"
149
+ - ".rubocop.yml"
78
150
  - ".travis.yml"
79
151
  - CHANGELOG.md
80
152
  - Gemfile
@@ -85,10 +157,14 @@ files:
85
157
  - bin/setup
86
158
  - lib/prontoforms.rb
87
159
  - lib/prontoforms/client.rb
160
+ - lib/prontoforms/document.rb
161
+ - lib/prontoforms/form.rb
162
+ - lib/prontoforms/form_iteration.rb
88
163
  - lib/prontoforms/form_space.rb
89
164
  - lib/prontoforms/form_submission.rb
90
165
  - lib/prontoforms/resource.rb
91
166
  - lib/prontoforms/resource_list.rb
167
+ - lib/prontoforms/user.rb
92
168
  - lib/prontoforms/version.rb
93
169
  - prontoforms.gemspec
94
170
  homepage: https://github.com/paulholden2/prontoforms
@@ -107,14 +183,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
183
  requirements:
108
184
  - - ">="
109
185
  - !ruby/object:Gem::Version
110
- version: 2.3.0
186
+ version: 2.6.0
111
187
  required_rubygems_version: !ruby/object:Gem::Requirement
112
188
  requirements:
113
189
  - - ">="
114
190
  - !ruby/object:Gem::Version
115
191
  version: '0'
116
192
  requirements: []
117
- rubygems_version: 3.0.8
193
+ rubygems_version: 3.1.4
118
194
  signing_key:
119
195
  specification_version: 4
120
196
  summary: A library for using the ProntoForms REST API in Ruby applications.