fixably 0.1.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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +18 -0
  3. data/.gitignore +14 -0
  4. data/.mutant.yml +23 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +145 -0
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +119 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +227 -0
  12. data/Rakefile +12 -0
  13. data/bin/console +15 -0
  14. data/bin/mutant +3 -0
  15. data/bin/setup +8 -0
  16. data/docs/customer/child.md +23 -0
  17. data/docs/customer.md +78 -0
  18. data/docs/device.md +56 -0
  19. data/docs/order/line.md +27 -0
  20. data/docs/order/note.md +34 -0
  21. data/docs/order/task.md +27 -0
  22. data/docs/order.md +121 -0
  23. data/docs/queue.md +36 -0
  24. data/docs/status.md +42 -0
  25. data/docs/user.md +23 -0
  26. data/fixably.gemspec +38 -0
  27. data/lib/fixably/action_policy.rb +94 -0
  28. data/lib/fixably/actions.rb +148 -0
  29. data/lib/fixably/active_resource/base.rb +53 -0
  30. data/lib/fixably/active_resource/paginated_collection.rb +91 -0
  31. data/lib/fixably/application_resource.rb +49 -0
  32. data/lib/fixably/argument_parameterisation.rb +77 -0
  33. data/lib/fixably/authorization.rb +17 -0
  34. data/lib/fixably/config.rb +39 -0
  35. data/lib/fixably/create_has_many_record.rb +90 -0
  36. data/lib/fixably/encoding.rb +38 -0
  37. data/lib/fixably/load_from_response.rb +116 -0
  38. data/lib/fixably/logger.rb +33 -0
  39. data/lib/fixably/resource_lazy_loader.rb +76 -0
  40. data/lib/fixably/resources/customer.rb +64 -0
  41. data/lib/fixably/resources/device.rb +27 -0
  42. data/lib/fixably/resources/order.rb +87 -0
  43. data/lib/fixably/resources/queue.rb +9 -0
  44. data/lib/fixably/resources/status.rb +12 -0
  45. data/lib/fixably/resources/user.rb +15 -0
  46. data/lib/fixably/version.rb +5 -0
  47. data/lib/fixably.rb +37 -0
  48. metadata +217 -0
data/README.md ADDED
@@ -0,0 +1,227 @@
1
+ # Fixably
2
+
3
+ The Fixably Ruby library provides access to the Fixably API for Ruby
4
+ applications with automatic integration into Ruby on Rails.
5
+
6
+ Support is only provided for Ruby >= 3.0
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem "fixably"
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle install
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install fixably
23
+
24
+ ## Configuration
25
+
26
+ Before you begin, you will need to setup API credentials in Fixably at
27
+ https://[your-domain].fixably.com/en/settings/integrations
28
+
29
+ You need to set your API key and subdomain in the Fixably configuration. The
30
+ subdomain is the part before .fixably.com when you are using Fixable. For
31
+ example, if you accessed Fixably via https://demo.fixably.com/, then your
32
+ subdomain is "demo".
33
+
34
+ ```ruby
35
+ require "fixably"
36
+
37
+ Fixably.configure do |config|
38
+ config.api_key = ENV["fixably_api_key"]
39
+ config.subdomain = "demo"
40
+ end
41
+ ```
42
+
43
+ In a Rails application, this is best done in an initializer. For example,
44
+ `config/initializers/fixably.rb`:
45
+ ```ruby
46
+ Fixably.configure do |config|
47
+ config.api_key = Rails.application.credentials.fixably["api_key"]
48
+ config.subdomain = Rails.application.credentials.fixably["subdomain"]
49
+ end
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ This gem utilises Active Resource under the hood to provide a Rails-like
55
+ interface.
56
+
57
+ ```ruby
58
+ customers = Fixably::Customer.all
59
+ customer = Fixably::Customer.find(1_000)
60
+ customer = Fixably::Customer.first
61
+ customer = Fixably::Customer.last
62
+
63
+ customers = Fixably::Customer.where(first_name: "HashNotAdam")
64
+ customer = customers.first
65
+ customer.first_name = "Adam"
66
+ customer.save!
67
+
68
+ customer = Fixably::Customer.create!(
69
+ first_name: "Adam",
70
+ last_name: "Rice",
71
+ email: "development@hashnotadam.com"
72
+ )
73
+ ```
74
+
75
+ Where there are known required fields, you can test validity or catch errors if
76
+ using the bang functions.
77
+
78
+ ```ruby
79
+ customer = Fixably::Customer.new(first_name: "HashNotAdam")
80
+ customer.valid? # => false
81
+ customer.errors.full_messages.to_sentence # => Either email or phone must be present
82
+
83
+ customer.save # => false
84
+ customer.save! # Exception: Failed. (ActiveResource::ResourceInvalid)
85
+
86
+ customer = Fixably::Customer.create(first_name: "HashNotAdam")
87
+ customer.persisted? # => false
88
+
89
+ customer = Fixably::Customer.create!(first_name: "HashNotAdam") # Exception: Failed. (ActiveResource::ResourceInvalid)
90
+ ```
91
+
92
+ If you need to know the attributes of a model, you can request the schema. It
93
+ should be noted that the schema only includes fields that Fixably accept when
94
+ creating or updating record. For example, if you load a customer, the API will
95
+ include an ID and tags but Fixably does not support modifying either attribute.
96
+
97
+ ```ruby
98
+ Fixably::Customer.schema
99
+ # =>
100
+ # {"first_name"=>"string",
101
+ # "last_name"=>"string",
102
+ # "company"=>"string",
103
+ # "phone"=>"string",
104
+ # "email"=>"string",
105
+ # "business_id"=>"string",
106
+ # "language"=>"string",
107
+ # "provider"=>"string",
108
+ # "identifier"=>"string"}
109
+ ```
110
+
111
+ We only use a small subset of the available resources so not all of the API is
112
+ implemented, however, this gem is designed in such a way to make it easy to add
113
+ new endpoints. If you need access to another resource, let's chat.
114
+
115
+ Currently supported resources:
116
+ - Fixably::Customer ([documentation](docs/customer.md))
117
+ - Fixably::Customer::Child ([documentation](docs/customer/child.md))
118
+ - Fixably::Device ([documentation](docs/device.md))
119
+ - Fixably::Order ([documentation](docs/order.md))
120
+ - Fixably::Order::Line ([documentation](docs/order/line.md))
121
+ - Fixably::Order::Note ([documentation](docs/order/note.md))
122
+ - Fixably::Order::Task ([documentation](docs/order/task.md))
123
+ - Fixably::Queue ([documentation](docs/queue.md))
124
+ - Fixably::Status ([documentation](docs/status.md))
125
+ - Fixably::User ([documentation](docs/user.md))
126
+
127
+ ## Link expansion
128
+
129
+ Fixably actively avoid sending information about associations or even the data
130
+ for a collection ([Fixably docs](https://docs.fixably.com/?http#link-expansion)).
131
+ For example, if you were to send a request for a collection of customers, you
132
+ would receive something like:
133
+ ```ruby
134
+ {
135
+ "limit": 25,
136
+ "offset": 0,
137
+ "totalItems": 100,
138
+ "items": [
139
+ { "href": "https://subdomain.fixably.com/api/v3/customers/1001" },
140
+ { "href": "https://subdomain.fixably.com/api/v3/customers/1002" },
141
+ { "href": "https://subdomain.fixably.com/api/v3/customers/1003" },
142
+ ...
143
+ ]
144
+ }
145
+ ```
146
+
147
+ This gem will always pass "expand=items" with requests which expands the first
148
+ layer of information. If you would also like to load associations, you can
149
+ use the `includes` method with the name of the association. For example:
150
+
151
+ ```ruby
152
+ customers = Fixably::Customer.includes(:children).all
153
+ # expand=items,children(items)
154
+ ```
155
+
156
+ ## Pagination
157
+
158
+ When making a request that could return multiple results, you will receive a
159
+ paginated collection. You can pass `limit` and `offset` parameters to manually
160
+ manage pagination or use the helper methods:
161
+ ```ruby
162
+ customers = Fixably::Customer.where(company: "Education Advantage") # PaginatedCollection
163
+ customers.limit # => 25
164
+ customers.offset # => 0
165
+
166
+ customers.each.count # => 25
167
+
168
+ all_customers = []
169
+ customers.paginated_each { all_customers << _1 }
170
+ all_customers.count # => 100
171
+
172
+ all_customers = customers.paginated_map
173
+ all_customers.count # => 100
174
+ ```
175
+
176
+ Remember to be respectful when using this feature; requesting all records has
177
+ the potential to send a lot of requests. If you need to download a lot of data,
178
+ it is probably worth your time to tweak the limit to pull in bigger batches:
179
+ ```ruby
180
+ customers = Fixably::Customer.all(limit: 100)
181
+ customers.limit # => 100
182
+ customers.offset # => 0
183
+
184
+ customers.each.count # => 25
185
+ ```
186
+
187
+ ## Contributing
188
+
189
+ Bug reports and pull requests are welcome on
190
+ [GitHub](https://github.com/HashNotAdam/fixably-ruby).
191
+ This project is intended to be a safe, welcoming space for collaboration, and
192
+ contributors are expected to adhere to the
193
+ [code of conduct](https://github.com/HashNotAdam/fixably-ruby/blob/master/CODE_OF_CONDUCT.md).
194
+
195
+ If you would like to add a feature or fix a bug:
196
+ - create an issue so we can discuss your thoughts;
197
+ - fork the project;
198
+ - start a feature/bugfix branch;
199
+ - commit your changes (be sure to include tests); and
200
+ - create a pull request to merge your branch into main.
201
+
202
+ Be aware that this gem monkey patches Active Resource. As such, you may need to
203
+ familiarise yourself with `lib/fixably/active_resource/base.rb`.
204
+
205
+ ## Testing
206
+
207
+ The test suite does not make any requests, however, it does test up to the point
208
+ that the request would be made. This means that many tests will fail unless
209
+ a subdomain and API key are configured.
210
+
211
+ The dotenv gem is loaded when tests are run and will look for a .env file in the
212
+ root directory. A .env.example file has been supplied so you copy it to .env and
213
+ replace the example values:
214
+
215
+ ```sh
216
+ cp .env.example .env
217
+ ```
218
+
219
+ ## License
220
+
221
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
222
+
223
+ ## Code of Conduct
224
+
225
+ Everyone interacting in the Fixably project's codebases, issue trackers, chat
226
+ rooms and mailing lists is expected to follow the
227
+ [code of conduct](https://github.com/HashNotAdam/fixably-ruby/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "fixably"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/mutant ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/zsh
2
+
3
+ MUTATION_TESTING=true bundle exec mutant run $@
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,23 @@
1
+ # Fixably::Customer::Child
2
+
3
+ ## List children
4
+
5
+ The Fixably API does not allow children to be searched
6
+
7
+ ## Get a child
8
+
9
+ ```ruby
10
+ Fixably::Customer::Child.find(1000, customer_id: 1000)
11
+ ```
12
+
13
+ ## Create a child
14
+
15
+ The Fixably API does not allow children to be created
16
+
17
+ ## Update a child
18
+
19
+ The Fixably API does not allow children to be updated
20
+
21
+ ## Destroy a child
22
+
23
+ The Fixably API does not allow children to be destroyed
data/docs/customer.md ADDED
@@ -0,0 +1,78 @@
1
+ # Fixably::Customer
2
+
3
+ ## List customers
4
+
5
+ ```ruby
6
+ Fixably::Customer.all
7
+ Fixably::Customer.where(first_name: "Adam")
8
+ ```
9
+
10
+ ### Include associations in a list
11
+
12
+ **Children**
13
+ ```ruby
14
+ Fixably::Customer.includes(:children).all
15
+ Fixably::Customer.includes(:children).where(first_name: "Adam")
16
+ ```
17
+
18
+ ## Get a customer
19
+
20
+ ```ruby
21
+ Fixably::Customer.find(1_000)
22
+ Fixably::Customer.first
23
+ Fixably::Customer.last
24
+ ```
25
+
26
+ ## Create a customer
27
+
28
+ ```ruby
29
+ customer = Fixably::Customer.create(
30
+ first_name: "Adam",
31
+ last_name: "Rice",
32
+ email: "development@hashnotadam.com"
33
+ )
34
+ customer.valid? # => true
35
+ customer.persisted? # => true
36
+
37
+ # Raises an error on failure
38
+ Fixably::Customer.create!(
39
+ first_name: "Adam",
40
+ last_name: "Rice",
41
+ email: "development@hashnotadam.com"
42
+ )
43
+
44
+ customer = Fixably::Customer.new(
45
+ first_name: "Adam",
46
+ last_name: "Rice",
47
+ email: "development@hashnotadam.com"
48
+ )
49
+ customer.save
50
+ customer.valid? # => true
51
+ customer.persisted? # => true
52
+
53
+ customer = Fixably::Customer.new(
54
+ first_name: "Adam",
55
+ last_name: "Rice",
56
+ email: "development@hashnotadam.com"
57
+ )
58
+ # Raises an error on failure
59
+ customer.save!
60
+ ```
61
+
62
+ ## Update a customer
63
+
64
+ ```ruby
65
+ customer = Fixably::Customer.find(1_000)
66
+ customer.first_name = "Adam"
67
+
68
+ customer.save
69
+ customer.valid? # => true
70
+ customer.persisted? # => true
71
+
72
+ # Raises an error on failure
73
+ customer.save!
74
+ ```
75
+
76
+ ## Destroy a customer
77
+
78
+ The Fixably API does not allow customers to be destroyed
data/docs/device.md ADDED
@@ -0,0 +1,56 @@
1
+ # Fixably::Device
2
+
3
+ ## List devices
4
+
5
+ ```ruby
6
+ Fixably::Device.all
7
+ Fixably::Device.where(serialNumber: "ABCDE123FGHI")
8
+ ```
9
+
10
+ ## Get a device
11
+
12
+ ```ruby
13
+ Fixably::Device.find(1_000)
14
+ Fixably::Device.first
15
+ Fixably::Device.last
16
+ ```
17
+
18
+ ## Create a device
19
+
20
+ ```ruby
21
+ device = Fixably::Device.create(
22
+ name: "My device",
23
+ serial_number: "ABCDE123FGHI"
24
+ )
25
+ device.valid? # => true
26
+ device.persisted? # => true
27
+
28
+ # Raises an error on failure
29
+ Fixably::Device.create!(
30
+ name: "My device",
31
+ serial_number: "ABCDE123FGHI"
32
+ )
33
+
34
+ device = Fixably::Device.new(
35
+ name: "My device",
36
+ serial_number: "ABCDE123FGHI"
37
+ )
38
+ device.save
39
+ device.valid? # => true
40
+ device.persisted? # => true
41
+
42
+ device = Fixably::Device.new(
43
+ name: "My device",
44
+ serial_number: "ABCDE123FGHI"
45
+ )
46
+ # Raises an error on failure
47
+ device.save!
48
+ ```
49
+
50
+ ## Update a device
51
+
52
+ The Fixably API does not allow devices to be updated
53
+
54
+ ## Destroy a device
55
+
56
+ The Fixably API does not allow devices to be destroyed
@@ -0,0 +1,27 @@
1
+ # Fixably::Order::Line
2
+
3
+ ## List order lines
4
+
5
+ ```ruby
6
+ Fixably::Order::Line.all(order_id: 1000)
7
+ ```
8
+
9
+ ## Get an order line
10
+
11
+ ```ruby
12
+ Fixably::Order::Line.find(1000, order_id: 1000)
13
+ Fixably::Order::Line.first(order_id: 1000)
14
+ Fixably::Order::Line.last(order_id: 1000)
15
+ ```
16
+
17
+ ## Create an order line
18
+
19
+ The Fixably API does not allow order lines to be created
20
+
21
+ ## Update an order line
22
+
23
+ While supported by Fixably, this feature has not yet been implemented
24
+
25
+ ## Destroy an order line
26
+
27
+ The Fixably API does not allow notes to be destroyed