prontoforms 0.2.0 → 2.0.1

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 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.