├── .gitignore ├── .rspec ├── .rubocop.yml ├── .ruby-gemset ├── .ruby-version ├── .travis.yml ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── VERSION ├── bin ├── cloudflair ├── console └── setup ├── cloudflair.gemspec ├── lib ├── cloudflair.rb └── cloudflair │ ├── api.rb │ ├── api │ ├── railguns.rb │ ├── zone.rb │ ├── zone │ │ ├── analytics.rb │ │ ├── available_plan.rb │ │ ├── available_rate_plan.rb │ │ ├── custom_hostname.rb │ │ ├── dns_record.rb │ │ ├── purge_cache.rb │ │ ├── railgun.rb │ │ ├── settings.rb │ │ └── settings │ │ │ ├── advanced_ddos.rb │ │ │ ├── always_online.rb │ │ │ ├── browser_cache_ttl.rb │ │ │ ├── browser_check.rb │ │ │ ├── cache_level.rb │ │ │ ├── challenge_ttl.rb │ │ │ ├── development_mode.rb │ │ │ ├── email_obfuscation.rb │ │ │ ├── hotlink_protection.rb │ │ │ ├── ip_geolocation.rb │ │ │ ├── ipv6.rb │ │ │ ├── minify.rb │ │ │ ├── mirage.rb │ │ │ ├── mobile_redirect.rb │ │ │ ├── origin_error_page_pass_thru.rb │ │ │ ├── polish.rb │ │ │ ├── prefetch_preload.rb │ │ │ ├── response_buffering.rb │ │ │ ├── rocket_loader.rb │ │ │ ├── security_header.rb │ │ │ ├── security_level.rb │ │ │ ├── server_side_exclude.rb │ │ │ ├── sort_query_string_for_cache.rb │ │ │ ├── ssl.rb │ │ │ ├── tls_1_2_only.rb │ │ │ ├── tls_1_3.rb │ │ │ ├── tls_client_auth.rb │ │ │ ├── true_client_ip_header.rb │ │ │ ├── waf.rb │ │ │ └── websockets.rb │ ├── zone__available_plans.rb │ ├── zone__custom_hostnames.rb │ ├── zone__dns_records.rb │ └── zone__railguns.rb │ ├── communication.rb │ ├── connection.rb │ ├── entity.rb │ ├── error │ ├── cloudflair_error.rb │ └── cloudflare_error.rb │ └── version.rb └── spec ├── cloudflair ├── api │ ├── railguns_spec.rb │ ├── zone │ │ ├── analytics_spec.rb │ │ ├── available_plan_spec.rb │ │ ├── available_rate_plan_spec.rb │ │ ├── custom_hostname_spec.rb │ │ ├── dns_record_spec.rb │ │ ├── purge_cache_spec.rb │ │ ├── railgun_spec.rb │ │ ├── settings │ │ │ ├── advanced_ddos_spec.rb │ │ │ ├── always_online_spec.rb │ │ │ ├── browser_cache_ttl_spec.rb │ │ │ ├── browser_check_spec.rb │ │ │ ├── cache_level_spec.rb │ │ │ ├── challenge_ttl_spec.rb │ │ │ ├── development_mode_spec.rb │ │ │ ├── email_obfuscation_spec.rb │ │ │ ├── hotlink_protection_spec.rb │ │ │ ├── ip_geolocation_spec.rb │ │ │ ├── ipv6_spec.rb │ │ │ ├── minify_spec.rb │ │ │ ├── mirage_spec.rb │ │ │ ├── mobile_redirect_spec.rb │ │ │ ├── origin_error_page_pass_thru_spec.rb │ │ │ ├── polish_spec.rb │ │ │ ├── prefetch_preload_spec.rb │ │ │ ├── response_buffering_spec.rb │ │ │ ├── rocket_loader_spec.rb │ │ │ ├── security_header_spec.rb │ │ │ ├── security_level_spec.rb │ │ │ ├── server_side_exclude_spec.rb │ │ │ ├── sort_query_string_for_cache_spec.rb │ │ │ ├── ssl_spec.rb │ │ │ ├── tls_1_2_only_spec.rb │ │ │ ├── tls_1_3_spec.rb │ │ │ ├── tls_client_auth_spec.rb │ │ │ ├── true_client_ip_header_spec.rb │ │ │ ├── waf_spec.rb │ │ │ └── websockets_spec.rb │ │ └── settings_spec.rb │ ├── zone__available_plans_spec.rb │ ├── zone__custom_hostnames_spec.rb │ ├── zone__dns_records_spec.rb │ ├── zone__railguns_spec.rb │ └── zone_spec.rb ├── api_railguns_spec.rb ├── api_zones_spec.rb ├── cloudflair_spec.rb ├── communication_spec.rb ├── connection_spec.rb ├── entity_array_objectfields_spec.rb ├── entity_spec.rb ├── error │ └── cloudflare_error_spec.rb └── fixtures │ ├── no_zones.json │ ├── railgun │ ├── delete.json │ ├── railgun.json │ └── railgun_zones.json │ ├── railguns.json │ ├── zone │ ├── analytics_colos.json │ ├── analytics_dashboard.json │ ├── available_rate_plans.json │ ├── custom_hostname.json │ ├── custom_hostname_deleted.json │ ├── custom_hostnames.json │ ├── delete.json │ ├── details.json │ ├── dns_record.json │ ├── dns_record_deleted.json │ ├── dns_records.json │ ├── plan.json │ ├── plans.json │ ├── purge_cache.json │ ├── railgun.json │ ├── railgun_diagnose.json │ ├── railguns.json │ └── settings │ │ ├── advanced_ddos.json │ │ ├── always_online.json │ │ ├── browser_cache_ttl.json │ │ ├── browser_check.json │ │ ├── cache_level.json │ │ ├── challenge_ttl.json │ │ ├── development_mode.json │ │ ├── development_mode_without_time_remaining.json │ │ ├── email_obfuscation.json │ │ ├── hotlink_protection.json │ │ ├── ip_geolocation.json │ │ ├── ipv6.json │ │ ├── minify.json │ │ ├── mirage.json │ │ ├── mobile_redirect.json │ │ ├── origin_error_page_pass_thru.json │ │ ├── polish.json │ │ ├── prefetch_preload.json │ │ ├── response_buffering.json │ │ ├── rocket_loader.json │ │ ├── security_header.json │ │ ├── security_level.json │ │ ├── server_side_exclude.json │ │ ├── sort_query_string_for_cache.json │ │ ├── ssl.json │ │ ├── tls_1_2_only.json │ │ ├── tls_1_3.json │ │ ├── tls_client_auth.json │ │ ├── true_client_ip_header.json │ │ ├── waf.json │ │ └── websockets.json │ └── zones.json ├── shared_context.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format progress 2 | --color 3 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - rubocop-performance 3 | - rubocop-rspec 4 | 5 | AllCops: 6 | Exclude: 7 | - 'bin/**/*' 8 | - 'db/**/*' 9 | TargetRubyVersion: 2.6.1 10 | 11 | Layout/AlignHash: 12 | EnforcedColonStyle: table 13 | EnforcedHashRocketStyle: table 14 | 15 | Metrics/BlockLength: 16 | Exclude: 17 | - Guardfile 18 | - 'spec/**/*spec.rb' 19 | 20 | Metrics/LineLength: 21 | Exclude: 22 | - Guardfile 23 | Max: 110 24 | 25 | Rails: 26 | Enabled: true 27 | 28 | Rails/HttpPositionalArguments: 29 | Exclude: 30 | 31 | Rails/SkipsModelValidations: 32 | Enabled: false 33 | 34 | RSpec/MultipleExpectations: 35 | Enabled: false 36 | 37 | Style/Documentation: 38 | Enabled: false 39 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | cloudflair 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.3.4 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: ruby 3 | before_install: gem install bundler 4 | rvm: 5 | - 2.3 6 | - 2.4 7 | notifications: 8 | email: 9 | on_success: never 10 | slack: 11 | secure: o1rlXNKZgQUIIfpzz//KpClcUS/ea5ECbbTaexQYHn84hqPNlsBdWhSrLg2s6MIJ1zSml4NBKQgwQJCV/6keel06XeNPvGPdQLVmSsBCWS4EJ/CvAAsXadghmSDYdsZlTaXvwa2ZdIaCHrM/SncZYi7I+KIiGsbV0KJgYVTlWGPWuN1kh3od1Ixw6W+TFUKONz8OqVFGo2yCr68zDtxUvrY8G/TNRRtWUINHPSIHL7+7JxzOtDZKOITptcLii8tmqi07HtmU7+78lDMlze8ejhchEDKoycTwVOQDRxjjLbDKZsV33nqG5XYRqW8FQv6zJ2c3eCfd2M2Lm+WkPe/ZBQ25Ok4/wK35T0oPt5lW6LKRNt202nQiI6vqn54489knOUpvA60z2r6taIgI3Os8kCdG8rX95Hob4gpU4zLqPNz26vqGiB0vz4DFSJWpRlYK15YT7SpEEMW2luPcTGHaclRSUFgjo/JkVH6zg+1rcMW4ZbKoxJZoNu+nmk9m1Xaz0r5tfJHBzB5XguRcKakRWkhb0rV4Nvo1as1PFtpxt9tiZsIXNTDNtf+upQeJs1Tevm6z4zBGXOIp//MIJEUyUkJ7Fkb+pyRbDOh30JSQJs0Z1y+/LA0rNkbQ+/jjeoKAepnFvawsXZF6UVWZxsBzAkIWTe+bwghnxX4Gm454RiI= 12 | deploy: 13 | provider: rubygems 14 | api_key: 15 | secure: GisVn77etjRfIwmjsktJVFU182lSuZqbQBsb8jkMoBr0/01fE/tWpZHOMNnKU5JoIaaQAGA0F1w+OXk/eAldvWHbu++074/XcgGerMBV5kxhBOpKEaSu5/cxUfgtGIi2eBBS4xe+GEwtlkI08c6BCiX9pUuUn8LwuUvN7NLNd7nLnZhhnawAoG75aWoMXnudqbIoX/1kGIem8XMuugWwxcr7PsnBy43Mj3yYXmtbO5IW4LC1sDywYc3O/lHmC7hner5yFJSa3kCNN9IMEieRW8/bZAlu3HncfJoORha3tZq37Po/kV8OBuYMoHwxQouCnrh0OW3QNrsmFF+tTy8z132GDjOIaNHwKZyvtXHgfmq4KXdSU5dTlDR5U4Z7jFTbOifc1+UuU1B3RHMHsrqtJgb5ihoXAjtZI8JSjQ7aI+bX9aSt3OpELymuAzoW1mV/Rf4kuNq23jmgDKBEhnR6YdQ864pFGnPL00kPhMUQ+iVX4OFQMZ2/eayYuNGz1LV1WDfFoFSsinZtr/erNnziYJHuzULfFdVg7+ZGMkmLFl7RHiRlphrylW+IN0K+hKEaTDFJ/yVYlLvr/OakR2l4kiPlxfQPXAtmh4MRe1vJdyT3RlGha9qecPddGuzWw3kG8A8bJv9H15YaplHRsu8HryMH5Zt5Tup8cnN37kMrILg= 16 | gem: cloudflair 17 | on: 18 | tags: true 19 | repo: ninech/cloudflair 20 | condition: "$TRAVIS_RUBY_VERSION == 2.4" 21 | skip_cleanup: true 22 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | # Specify your gem's dependencies in cloudflair.gemspec 6 | gemspec 7 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Christian Mäder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloudflair 2 | 3 | [![Build Status](https://travis-ci.org/ninech/cloudflair.svg?branch=master)](https://travis-ci.org/ninech/cloudflair) 4 | [![Gem Version](https://badge.fury.io/rb/cloudflair.svg)](https://badge.fury.io/rb/cloudflair) 5 | 6 | A simple Ruby-wrapper around Cloudflare's v4 API. 7 | 8 | ## Installation 9 | 10 | Add this line to your application's Gemfile: 11 | 12 | ```ruby 13 | gem 'cloudflair' 14 | ``` 15 | 16 | And then execute: 17 | 18 | $ bundle 19 | 20 | Or install it yourself as: 21 | 22 | $ gem install cloudflair 23 | 24 | ## A Note on Faraday 25 | 26 | We have decided to not tightly control the version of faraday (anymore). The versions of faraday that are known to work are listed below. If you want to update to a newer version, you're doing it at your own risk. (But if it works, which is usually when all specs pass, please send a PR to update the list below.) 27 | 28 | To be on the safe side, we recommend to lock `faraday` to any of the versions listed below. This can be done like this: 29 | 30 | ```ruby 31 | gem 'cloudflair' 32 | gem 'faraday', '>=0.13', '<0.14' 33 | ``` 34 | 35 | ### Faraday Versions known to work 36 | 37 | * `gem 'faraday', '>= 0.12', '<= 0.13'` 38 | * `gem 'faraday', '>= 0.13', '<= 0.14'` (starting with `gem 'cloudflair', '>= 0.2.0'`) 39 | 40 | ## Usage 41 | 42 | ### Configuration 43 | 44 | Put this somewhere, where it runs, before any call to anything else of Cloudflair. 45 | If you are using Rails, then this would probably be somewhere beneath `/config`. 46 | 47 | ```ruby 48 | require 'cloudflair' 49 | Cloudflair.configure do |config| 50 | config.cloudflare.auth.key = 'YOUR_API_KEY' 51 | config.cloudflare.auth.email = 'YOUR_ACCOUNT_EMAIL' 52 | # if you have a user_service_key, you don't need auth.key and auth.email 53 | config.cloudflare.auth.user_service_key = 'YOUR_USER_SERVICE_KEY' 54 | 55 | # these are optional: 56 | config.cloudflare.api_base_url = 'https://your_cloudflare_mock.local' 57 | config.faraday.adapter = :your_preferred_faraday_adapter 58 | # built-in options: :logger, :detailed_logger; default: nil 59 | config.faraday.logger = :logger 60 | end 61 | ``` 62 | 63 | ### Call An API Endpoint 64 | 65 | This gem is organized along the URL schema of Cloudflare (as shown in the examples below). So you're good off to check the original Cloudflare [API documentation](https://api.cloudflare.com) for more information on the URL schema. 66 | 67 | ```ruby 68 | require 'cloudflair' 69 | 70 | # GET https://api.cloudflare.com/client/v4/railguns 71 | Cloudflair.railguns 72 | # => [...] 73 | 74 | # GET https://api.cloudflare.com/client/v4/zones 75 | Cloudflair.zones 76 | # => [...] 77 | 78 | # GET https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0 79 | Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').name 80 | # => "blog.example.com" 81 | 82 | # GET https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0/settings/development_mode 83 | Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').settings.development_mode.value 84 | # => "on" 85 | # => "off" 86 | 87 | # PATCH https://api.cloudflare.com/client/v4/zones/cd7d068de3012345da9420df9514dad0/settings/development_mode 88 | # {"value"="on"} 89 | Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').settings.development_mode.tap do |dm| 90 | dm.value = 'on' 91 | dm.save 92 | end 93 | 94 | # GET https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59 95 | Cloudflair.zone('023e105f4ecef8ad9ca31a8372d0c353').dns_record('372e67954025e0ba6aaa6d586b9e0b59').name 96 | # => "examples.com" 97 | ``` 98 | 99 | You can use any field that Cloudflare's API returns. If a field is covered by some internal field, use `_field`. When you set a new value for a field and then want to access original value, you can use `field!` and `_field!`, respectively. 100 | 101 | A good reference on how to use this wrapper are also the Rspecs. 102 | 103 | ## Implemented Endpoints 104 | 105 | * `/railguns` GET, POST 106 | * `/railguns/:railgun_id` GET, PATCH, DELETE 107 | * `/railguns/:railgun_id/zones` GET 108 | * `/zones` GET, POST 109 | * `/zones/:zone_id` GET, PATCH, DELETE 110 | * `/zones/:zone_id/analytics/dashboard` GET 111 | * `/zones/:zone_id/analytics/colos` GET 112 | * `/zones/:zone_id/available_plans` GET 113 | * `/zones/:zone_id/available_plans/:plan_id` GET 114 | * `/zones/:zone_id/available_rate_plans` 115 | * `/zones/:zone_id/custom_hostnames` GET, POST, PATCH 116 | * `/zones/:zone_id/dns_records` GET, POST 117 | * `/zones/:zone_id/dns_records/:record_id` GET, DELETE (PUT not implemented) 118 | * `/zones/:zone_id/purge_cache` POST 119 | * `/zones/:zone_id/railguns` GET 120 | * `/zones/:zone_id/railguns/:railgun_id` GET 121 | * `/zones/:zone_id/railguns/:railgun_id/diagnose` GET, PATCH 122 | * `/zones/:zone_id/settings/advanced_ddos` GET 123 | * `/zones/:zone_id/settings/always_online` GET, PATCH 124 | * `/zones/:zone_id/settings/browser_cache_ttl` GET, PATCH 125 | * `/zones/:zone_id/settings/browser_check` GET, PATCH 126 | * `/zones/:zone_id/settings/cache_level` GET, PATCH 127 | * `/zones/:zone_id/settings/challenge_ttl` GET, PATCH 128 | * `/zones/:zone_id/settings/development_mode` GET, PATCH 129 | * `/zones/:zone_id/settings/email_obfuscation` GET, PATCH 130 | * `/zones/:zone_id/settings/hotlink_protection` GET, PATCH 131 | * `/zones/:zone_id/settings/ip_geolocation` GET, PATCH 132 | * `/zones/:zone_id/settings/ipv6` GET, PATCH 133 | * `/zones/:zone_id/settings/minify` GET, PATCH 134 | * `/zones/:zone_id/settings/mirage` GET, PATCH 135 | * `/zones/:zone_id/settings/mobile_redirect` GET, PATCH 136 | * `/zones/:zone_id/settings/origin_error_page_pass_thru` GET, PATCH 137 | * `/zones/:zone_id/settings/polish` GET, PATCH 138 | * `/zones/:zone_id/settings/prefetch_preload` GET, PATCH 139 | * `/zones/:zone_id/settings/response_buffering` GET, PATCH 140 | * `/zones/:zone_id/settings/rocket_loader` GET, PATCH 141 | * `/zones/:zone_id/settings/security_header` GET, PATCH 142 | * `/zones/:zone_id/settings/server_side_exclude` GET, PATCH 143 | * `/zones/:zone_id/settings/server_level` GET, PATCH 144 | * `/zones/:zone_id/settings/sort_query_string_for_cache` GET, PATCH 145 | * `/zones/:zone_id/settings/ssl` GET, PATCH 146 | * `/zones/:zone_id/settings/tls_1_2_only` GET, PATCH 147 | * `/zones/:zone_id/settings/tls_1_3` GET, PATCH 148 | * `/zones/:zone_id/settings/tls_client_auth` GET, PATCH 149 | * `/zones/:zone_id/settings/true_client_ip_header` GET, PATCH 150 | * `/zones/:zone_id/settings/waf` GET, PATCH 151 | * `/zones/:zone_id/settings/websockets` GET, PATCH 152 | 153 | ## Development 154 | 155 | After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. 156 | 157 | To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). 158 | 159 | ### Developing Guidelines 160 | 161 | * The number one aim of this API wrapper is to mimic the Cloudflare API as it is laid out in the URL. So if the url is `/zones/:zone_id/analytics/dashboard`, then the corresponding Ruby code should become `Cloudflair.zones('abcdefg').analytics.dashboard`. 162 | * The API should load resources only when required to. So `Cloudflair.zones('abcdefg')` alone would not call out to Cloudflare, but only when `Cloudflair.zones('abcdefg').name` is called. Likewise, `Cloudflair.zones` will immediately call Cloudflare, as it requires the result immediately. (Unless we begin to introduce a kind of 'delayed Array'. Yet we probably don't want that.) 163 | * Adding additional wrappers for the API shall be easy and done in only a few minutes. (Most of the `/zones/:zone_id/settings/*` API calls were implemented in about five minutes.) So the cloudflair internal API should hide the complexity away. (E.g. the complexity of the fetching, parsing, error handling, etc. should be hidden away. See `Connection`, `Communication` and `Entity`, which contain almost all of the complexity of this Gem.) 164 | * Please write Rspecs for each new API endpoint. Use the JSON provided in the official Cloudflare API documentation as test data. 165 | 166 | ## Contributing 167 | 168 | Bug reports and pull requests are welcome on GitHub at [ninech/cloudflair](https://github.com/ninech/cloudflair). 169 | 170 | ### Whishlist 171 | 172 | * Full API support 173 | * Metrics reporting 174 | * Rate Limit Tracking 175 | 176 | ## License 177 | 178 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). 179 | 180 | ## About 181 | 182 | This gem is currently maintained and funded by [nine](https://nine.ch). 183 | 184 | [![logo of the company 'nine'](https://logo.apps.at-nine.ch/Dmqied_eSaoBMQwk3vVgn4UIgDo=/trim/500x0/logo_claim.png)](https://www.nine.ch) 185 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 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 | task default: :spec 9 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.4.0 2 | -------------------------------------------------------------------------------- /bin/cloudflair: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'bundler/setup' 4 | require 'cloudflair' 5 | require 'dotenv' 6 | 7 | Dotenv.load 8 | 9 | Cloudflair.configure do |c| 10 | c.cloudflare.auth.key = ENV['AUTH_KEY'] 11 | c.cloudflare.auth.email = ENV['AUTH_MAIL'] 12 | c.faraday.logger = :detailed_logger 13 | end 14 | 15 | if ENV['CF_ZONE'] 16 | def z 17 | @z ||= Cloudflair.zone ENV['CF_ZONE'] 18 | end 19 | end 20 | 21 | require 'irb' 22 | IRB.start 23 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'bundler/setup' 4 | require 'cloudflair' 5 | 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 | IRB.start 15 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 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 9 | -------------------------------------------------------------------------------- /cloudflair.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | lib = File.expand_path('lib', __dir__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | require 'cloudflair/version' 6 | 7 | Gem::Specification.new do |spec| 8 | spec.name = 'cloudflair' 9 | spec.version = File.read('VERSION') 10 | spec.authors = ['Christian Mäder'] 11 | spec.email = %w[christian.maeder@nine.ch] 12 | 13 | spec.summary = "Wrapper to CloudFlare's v4 REST API." 14 | spec.description = "Cloudflair aims to provide easy access to CloudFlare's public API." 15 | spec.homepage = 'https://github.com/ninech/cloudflair' 16 | spec.license = 'MIT' 17 | 18 | spec.metadata['allowed_push_host'] = 'https://rubygems.org' 19 | 20 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 21 | spec.bindir = 'exe' 22 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 23 | spec.require_paths = %w[lib] 24 | 25 | spec.add_runtime_dependency "dry-configurable", "> 0.12" 26 | spec.add_runtime_dependency 'faraday', '>= 0.10.0' 27 | spec.add_runtime_dependency 'faraday-detailed_logger' 28 | spec.add_runtime_dependency 'faraday_middleware' 29 | 30 | spec.add_development_dependency 'bundler', '~> 2.0.0' 31 | spec.add_development_dependency 'dotenv', '~> 2.1' 32 | spec.add_development_dependency 'rake', '~> 12.0' 33 | spec.add_development_dependency 'rspec', '~> 3.0' 34 | spec.add_development_dependency 'rubocop', '~> 0.48' 35 | spec.add_development_dependency 'rubocop-performance' 36 | spec.add_development_dependency 'rubocop-rspec', '~> 1.15' 37 | end 38 | -------------------------------------------------------------------------------- /lib/cloudflair.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api' 4 | require 'cloudflair/version' 5 | require 'dry-configurable' 6 | 7 | ## 8 | # To configure cloudflair 9 | # 10 | # require "cloudflair" 11 | # Cloudflair.configure do |config| 12 | # config.cloudflare.auth.key = 'YOUR_API_KEY' 13 | # config.cloudflare.auth.email = 'YOUR_ACCOUNT_EMAIL' 14 | # # if you have a user_service_key, you don't need auth.key and auth.email 15 | # config.cloudflare.auth.user_service_key = 'YOUR_USER_SERVICE_KEY' 16 | # 17 | # # these are optional: 18 | # 19 | # config.cloudflare.api_base_url = 'https://your_cloudflare_mock.local' 20 | # config.faraday.adapter = :your_preferred_faraday_adapter 21 | # # built-in options: :logger, :detailed_logger; default: nil 22 | # config.faraday.logger = :logger 23 | # end 24 | # 25 | module Cloudflair 26 | # Your code goes here... 27 | extend Dry::Configurable 28 | 29 | setting :cloudflare do 30 | setting :api_base_url, default: "https://api.cloudflare.com/client/v4/" 31 | setting :auth do 32 | setting :key 33 | setting :email 34 | setting :user_service_key 35 | end 36 | end 37 | 38 | setting :faraday do 39 | setting :adapter, default: :net_http 40 | setting :logger 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/cloudflair/api.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api/zone' 4 | require 'cloudflair/api/railguns' 5 | require 'cloudflair/communication' 6 | 7 | module Cloudflair 8 | extend Cloudflair::Communication 9 | 10 | def self.zone(zone_id) 11 | Zone.new zone_id 12 | end 13 | 14 | def self.zones(filter = {}) 15 | raw_zones = response connection.get 'zones', filter 16 | 17 | raw_zones.map do |raw_zone| 18 | zone = Zone.new(raw_zone['id']) 19 | zone.data = raw_zone 20 | zone 21 | end 22 | end 23 | 24 | def self.railgun(railgun_id) 25 | Railguns.new railgun_id 26 | end 27 | 28 | def self.railguns(filter = {}) 29 | raw_railguns = response connection.get 'railguns', filter 30 | 31 | raw_railguns.map do |raw_railgun| 32 | railgun = Railguns.new(raw_railgun['id']) 33 | railgun.data = raw_railgun 34 | railgun 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/cloudflair/api/railguns.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Railguns 7 | include Cloudflair::Entity 8 | 9 | attr_reader :railgun_id 10 | patchable_fields :enabled 11 | deletable true 12 | path 'railguns/:railgun_id' 13 | 14 | def initialize(railgun_id) 15 | @railgun_id = railgun_id 16 | end 17 | 18 | def zones 19 | raw_response = connection.get "#{path}/zones" 20 | parsed_responses = response raw_response 21 | parsed_responses.map do |parsed_response| 22 | hash_to_object parsed_response 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api/zone/analytics' 4 | require 'cloudflair/api/zone/available_plan' 5 | require 'cloudflair/api/zone/available_rate_plan' 6 | require 'cloudflair/api/zone/purge_cache' 7 | require 'cloudflair/api/zone/settings' 8 | require 'cloudflair/entity' 9 | 10 | module Cloudflair 11 | class Zone 12 | include Cloudflair::Entity 13 | 14 | require 'cloudflair/api/zone__dns_records' 15 | require 'cloudflair/api/zone__available_plans' 16 | require 'cloudflair/api/zone__railguns' 17 | require 'cloudflair/api/zone__custom_hostnames' 18 | 19 | attr_reader :zone_id 20 | 21 | patchable_fields :paused, :vanity_name_servers, :plan 22 | object_fields :plan, :plan_pending, :owner 23 | deletable true 24 | path 'zones/:zone_id' 25 | 26 | def initialize(zone_id) 27 | @zone_id = zone_id 28 | end 29 | 30 | def settings 31 | Cloudflair::Settings.new zone_id 32 | end 33 | 34 | def purge_cache 35 | Cloudflair::PurgeCache.new zone_id 36 | end 37 | 38 | def available_rate_plans 39 | Cloudflair::AvailableRatePlan.new zone_id 40 | end 41 | 42 | def analytics 43 | Cloudflair::Analytics.new zone_id 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/analytics.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Analytics 7 | include Cloudflair::Communication 8 | 9 | def initialize(zone_id) 10 | @path = "zones/#{zone_id}/analytics" 11 | end 12 | 13 | def dashboard(filter = {}) 14 | raw_response = connection.get "#{@path}/dashboard", filter 15 | parsed_response = response raw_response 16 | hash_to_object parsed_response 17 | end 18 | 19 | def colos(filter = {}) 20 | raw_response = connection.get "#{@path}/colos", filter 21 | parsed_responses = response raw_response 22 | parsed_responses.map do |parsed_response| 23 | hash_to_object parsed_response 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/available_plan.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class AvailablePlan 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id, :plan_id 10 | 11 | path 'zones/:zone_id/available_plans/:plan_id' 12 | 13 | def initialize(zone_id, plan_id) 14 | @zone_id = zone_id 15 | @plan_id = plan_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/available_rate_plan.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class AvailableRatePlan 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | array_object_fields :components 11 | path 'zones/:zone_id/available_rate_plans' 12 | 13 | def initialize(zone_id) 14 | @zone_id = zone_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/custom_hostname.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class CustomHostname 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id, :custom_hostname_id 10 | deletable true 11 | patchable_fields :ssl, :custom_origin_server, :custom_metadata 12 | path 'zones/:zone_id/custom_hostnames/:custom_hostname_id' 13 | 14 | def initialize(zone_id, custom_hostname_id) 15 | @zone_id = zone_id 16 | @custom_hostname_id = custom_hostname_id 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/dns_record.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class DnsRecord 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id, :record_id 10 | deletable true 11 | patchable_fields :content 12 | path 'zones/:zone_id/dns_records/:record_id' 13 | 14 | def initialize(zone_id, record_id) 15 | @zone_id = zone_id 16 | @record_id = record_id 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/purge_cache.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/communication' 4 | 5 | module Cloudflair 6 | class PurgeCache 7 | attr_reader :zone_id 8 | 9 | include Cloudflair::Communication 10 | 11 | def initialize(zone_id) 12 | @zone_id = zone_id 13 | end 14 | 15 | ## 16 | # @param purge_everything must be set to true 17 | def everything(purge_everything) 18 | resp = connection.post(path) { |req| req.body = { purge_everything: purge_everything } } 19 | response resp 20 | self 21 | end 22 | 23 | ## 24 | # @param [Hash] cache_identifier Consists of :files and :tags, which are String Arrays themselves. Sample: {files: ['https://foo.bar/index.htmll'], tags: ['css','js']} 25 | def selective(cache_identifier = {}) 26 | return self if cache_identifier.nil? || cache_identifier.empty? 27 | 28 | resp = connection.post(path) { |req| req.body = cache_identifier } 29 | response resp 30 | self 31 | end 32 | 33 | def path 34 | "zones/#{zone_id}/purge_cache" 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/railgun.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Railgun 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id, :railgun_id 10 | patchable_fields :connected 11 | path 'zones/:zone_id/railguns/:railgun_id' 12 | 13 | def initialize(zone_id, railgun_id) 14 | @zone_id = zone_id 15 | @railgun_id = railgun_id 16 | end 17 | 18 | def diagnose 19 | raw_response = connection.get "#{path}/diagnose" 20 | parsed_response = response raw_response 21 | hash_to_object parsed_response 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api/zone/settings/advanced_ddos' 4 | require 'cloudflair/api/zone/settings/always_online' 5 | require 'cloudflair/api/zone/settings/browser_cache_ttl' 6 | require 'cloudflair/api/zone/settings/browser_check' 7 | require 'cloudflair/api/zone/settings/cache_level' 8 | require 'cloudflair/api/zone/settings/challenge_ttl' 9 | require 'cloudflair/api/zone/settings/development_mode' 10 | require 'cloudflair/api/zone/settings/email_obfuscation' 11 | require 'cloudflair/api/zone/settings/hotlink_protection' 12 | require 'cloudflair/api/zone/settings/ip_geolocation' 13 | require 'cloudflair/api/zone/settings/ipv6' 14 | require 'cloudflair/api/zone/settings/minify' 15 | require 'cloudflair/api/zone/settings/mirage' 16 | require 'cloudflair/api/zone/settings/mobile_redirect' 17 | require 'cloudflair/api/zone/settings/origin_error_page_pass_thru' 18 | require 'cloudflair/api/zone/settings/polish' 19 | require 'cloudflair/api/zone/settings/prefetch_preload' 20 | require 'cloudflair/api/zone/settings/response_buffering' 21 | require 'cloudflair/api/zone/settings/rocket_loader' 22 | require 'cloudflair/api/zone/settings/security_header' 23 | require 'cloudflair/api/zone/settings/security_level' 24 | require 'cloudflair/api/zone/settings/server_side_exclude' 25 | require 'cloudflair/api/zone/settings/sort_query_string_for_cache' 26 | require 'cloudflair/api/zone/settings/ssl' 27 | require 'cloudflair/api/zone/settings/tls_client_auth' 28 | require 'cloudflair/api/zone/settings/tls_1_2_only' 29 | require 'cloudflair/api/zone/settings/tls_1_3' 30 | require 'cloudflair/api/zone/settings/true_client_ip_header' 31 | require 'cloudflair/api/zone/settings/waf' 32 | require 'cloudflair/api/zone/settings/websockets' 33 | 34 | module Cloudflair 35 | class Settings 36 | attr_reader :zone_id 37 | 38 | def initialize(zone_id) 39 | @zone_id = zone_id 40 | end 41 | 42 | { 43 | advanced_ddos: Cloudflair::AdvancedDdos, 44 | always_online: Cloudflair::AlwaysOnline, 45 | browser_cache_ttl: Cloudflair::BrowserCacheTtl, 46 | browser_check: Cloudflair::BrowserCheck, 47 | cache_level: Cloudflair::CacheLevel, 48 | challenge_ttl: Cloudflair::ChallengeTtl, 49 | development_mode: Cloudflair::DevelopmentMode, 50 | email_obfuscation: Cloudflair::EmailObfuscation, 51 | hotlink_protection: Cloudflair::HotlinkProtection, 52 | ip_geolocation: Cloudflair::IpGeolocation, 53 | ipv6: Cloudflair::Ipv6, 54 | minify: Cloudflair::Minify, 55 | mirage: Cloudflair::Mirage, 56 | mobile_redirect: Cloudflair::MobileRedirect, 57 | origin_error_page_pass_thru: Cloudflair::OriginErrorPagePassThru, 58 | polish: Cloudflair::Polish, 59 | prefetch_preload: Cloudflair::PrefetchPreload, 60 | response_buffering: Cloudflair::ResponseBuffering, 61 | rocket_loader: Cloudflair::RocketLoader, 62 | security_header: Cloudflair::SecurityHeader, 63 | security_level: Cloudflair::SecurityLevel, 64 | server_side_exclude: Cloudflair::ServerSideExclude, 65 | sort_query_string_for_cache: Cloudflair::SortQueryStringForCache, 66 | ssl: Cloudflair::Ssl, 67 | tls_client_auth: Cloudflair::TlsClientAuth, 68 | tls_1_2_only: Cloudflair::Tls12Only, 69 | tls_1_3: Cloudflair::Tls13, 70 | true_client_ip_header: Cloudflair::TrueClientIpHeader, 71 | waf: Cloudflair::Waf, 72 | websockets: Cloudflair::Websockets 73 | }.each do |method, klass| 74 | define_method method do 75 | klass.new @zone_id 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/advanced_ddos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class AdvancedDdos 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | path 'zones/:zone_id/settings/advanced_ddos' 12 | 13 | def initialize(zone_id) 14 | @zone_id = zone_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/always_online.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class AlwaysOnline 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/always_online' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/browser_cache_ttl.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class BrowserCacheTtl 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/browser_cache_ttl' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/browser_check.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class BrowserCheck 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/browser_check' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/cache_level.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class CacheLevel 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/cache_level' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/challenge_ttl.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class ChallengeTtl 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/challenge_ttl' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/development_mode.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class DevelopmentMode 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/development_mode' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | 18 | def time_remaining 19 | data.fetch('time_remaining', 0) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/email_obfuscation.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class EmailObfuscation 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/email_obfuscation' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/hotlink_protection.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class HotlinkProtection 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/hotlink_protection' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/ip_geolocation.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class IpGeolocation 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/ip_geolocation' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/ipv6.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Ipv6 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/ipv6' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/minify.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Minify 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/minify' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/mirage.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Mirage 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/mirage' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/mobile_redirect.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class MobileRedirect 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/mobile_redirect' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/origin_error_page_pass_thru.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class OriginErrorPagePassThru 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | path 'zones/:zone_id/settings/origin_error_page_pass_thru' 12 | 13 | def initialize(zone_id) 14 | @zone_id = zone_id 15 | end 16 | 17 | def value 18 | _raw_data! 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/polish.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Polish 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/polish' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/prefetch_preload.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class PrefetchPreload 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/prefetch_preload' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | 18 | def value 19 | _raw_data! 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/response_buffering.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class ResponseBuffering 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/response_buffering' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | 18 | def value 19 | _raw_data! 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/rocket_loader.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class RocketLoader 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/rocket_loader' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/security_header.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class SecurityHeader 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/security_header' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/security_level.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class SecurityLevel 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/security_level' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/server_side_exclude.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class ServerSideExclude 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/server_side_exclude' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/sort_query_string_for_cache.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class SortQueryStringForCache 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | path 'zones/:zone_id/settings/sort_query_string_for_cache' 12 | 13 | def initialize(zone_id) 14 | @zone_id = zone_id 15 | end 16 | 17 | def value 18 | _raw_data! 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/ssl.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Ssl 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/ssl' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/tls_1_2_only.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Tls12Only 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/tls_1_2_only' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | 18 | def value 19 | _raw_data! 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/tls_1_3.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Tls13 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/tls_1_3' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | 18 | def value 19 | _raw_data! 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/tls_client_auth.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class TlsClientAuth 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/tls_client_auth' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/true_client_ip_header.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class TrueClientIpHeader 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | patchable_fields :value 11 | path 'zones/:zone_id/settings/true_client_ip_header' 12 | 13 | def initialize(zone_id) 14 | @zone_id = zone_id 15 | end 16 | 17 | def value 18 | _raw_data! 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/waf.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Waf 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/waf' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone/settings/websockets.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/entity' 4 | 5 | module Cloudflair 6 | class Websockets 7 | include Cloudflair::Entity 8 | 9 | attr_reader :zone_id 10 | 11 | patchable_fields :value 12 | path 'zones/:zone_id/settings/websockets' 13 | 14 | def initialize(zone_id) 15 | @zone_id = zone_id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone__available_plans.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api/zone/available_plan' 4 | 5 | module Cloudflair 6 | class Zone 7 | def available_plans 8 | raw_plans = response connection.get("#{path}/available_plans") 9 | 10 | raw_plans.map do |raw_plan| 11 | zone = available_plan raw_plan['id'] 12 | zone.data = raw_plan 13 | zone 14 | end 15 | end 16 | 17 | def available_plan(plan_id) 18 | Cloudflair::AvailablePlan.new zone_id, plan_id 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone__custom_hostnames.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api/zone/custom_hostname' 4 | 5 | module Cloudflair 6 | class Zone 7 | def custom_hostnames(filter = {}) 8 | raw_hostnames = response connection.get("#{path}/custom_hostnames", filter) 9 | 10 | raw_hostnames.map { |raw_hostname| build_custom_hostname(raw_hostname) } 11 | end 12 | 13 | def custom_hostname(custom_hostname_id) 14 | Cloudflair::CustomHostname.new zone_id, custom_hostname_id 15 | end 16 | 17 | def new_custom_hostname(hostname_data) 18 | raw_hostname = response connection.post("#{path}/custom_hostnames", hostname_data) 19 | 20 | build_custom_hostname raw_hostname 21 | end 22 | 23 | private 24 | 25 | def build_custom_hostname(raw_hostname) 26 | hostname = custom_hostname raw_hostname['id'] 27 | hostname.data = raw_hostname 28 | hostname 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone__dns_records.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api/zone/dns_record' 4 | 5 | module Cloudflair 6 | class Zone 7 | def dns_records(filter = {}) 8 | raw_records = response connection.get("#{path}/dns_records", filter) 9 | raw_records.map { |raw_record| build_dns_record(raw_record) } 10 | end 11 | 12 | def dns_record(record_id) 13 | Cloudflair::DnsRecord.new zone_id, record_id 14 | end 15 | 16 | def new_dns_record(record_data) 17 | raw_record = response connection.post("#{path}/dns_records", record_data) 18 | build_dns_record raw_record 19 | end 20 | 21 | private 22 | 23 | def build_dns_record(raw_record) 24 | record = dns_record raw_record['id'] 25 | record.data = raw_record 26 | record 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/cloudflair/api/zone__railguns.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/api/zone/railgun' 4 | 5 | module Cloudflair 6 | class Zone 7 | def railguns(filter = {}) 8 | raw_railguns = response connection.get("#{path}/railguns", filter) 9 | 10 | raw_railguns.map do |raw_railgun| 11 | railgun = railgun raw_railgun['id'] 12 | railgun.data = raw_railgun 13 | railgun 14 | end 15 | end 16 | 17 | def railgun(railgun_id) 18 | Cloudflair::Railgun.new zone_id, railgun_id 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/cloudflair/communication.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/error/cloudflare_error' 4 | require 'cloudflair/error/cloudflair_error' 5 | require 'cloudflair/connection' 6 | 7 | module Cloudflair 8 | module Communication 9 | def response(response) 10 | return nil if response.status == 304 11 | 12 | raise_on_http_error response.status 13 | 14 | read response 15 | end 16 | 17 | def connection 18 | Cloudflair::Connection.new 19 | end 20 | 21 | def hash_to_object(hash) 22 | objectified_class = Class.new 23 | objectified_instance = objectified_class.new 24 | hash.each do |k, v| 25 | variable_name = sanitize_variable_name(k) 26 | variable_name = "_#{variable_name}" if objectified_instance.methods.map(&:to_s).include?(variable_name) 27 | 28 | objectified_instance.instance_variable_set("@#{variable_name}", v) 29 | objectified_class.send :define_method, variable_name, proc { instance_variable_get("@#{variable_name}") } 30 | end 31 | objectified_instance 32 | end 33 | 34 | private 35 | 36 | def read(response) 37 | body = response.body 38 | 39 | unless body['success'] 40 | raise Cloudflair::CloudflairError, "Unrecognized response format: '#{body}'" unless body['errors'] 41 | 42 | raise Cloudflair::CloudflareError, body['errors'] 43 | end 44 | 45 | body['result'] 46 | end 47 | 48 | def raise_on_http_error(status) 49 | case status 50 | when 200..399 51 | when 400..499 52 | raise_on_http_client_error status 53 | when 500..599 54 | raise Cloudflair::CloudflairError, "#{status} Remote Error" 55 | else 56 | raise Cloudflair::CloudflairError, "#{status} Unknown Error Code" 57 | end 58 | end 59 | 60 | def raise_on_http_client_error(status) 61 | case status 62 | when 400 63 | raise Cloudflair::CloudflairError, '400 Bad Request' 64 | when 401 65 | raise Cloudflair::CloudflairError, '401 Unauthorized' 66 | when 403 67 | raise Cloudflair::CloudflairError, '403 Forbidden' 68 | when 405 69 | raise Cloudflair::CloudflairError, '405 Method Not Allowed' 70 | when 415 71 | raise Cloudflair::CloudflairError, '415 Unsupported Media Type' 72 | when 429 73 | raise Cloudflair::CloudflairError, '429 Too Many Requests' 74 | else 75 | raise Cloudflair::CloudflairError, "#{status} Request Error" 76 | end 77 | end 78 | 79 | def sanitize_variable_name(raw_name) 80 | raw_name.gsub(/[^a-zA-Z0-9_]/, '_') 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /lib/cloudflair/connection.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'faraday' 4 | require 'faraday_middleware' 5 | require 'faraday/detailed_logger' 6 | require 'cloudflair/error/cloudflair_error' 7 | 8 | module Cloudflair 9 | class Connection 10 | def self.new 11 | config = Cloudflair.config 12 | new_faraday_from config 13 | end 14 | 15 | def self.headers # rubocop:disable Metrics/AbcSize, Metrics/MethodLength 16 | cloudflare_auth_config = Cloudflair.config.cloudflare.auth 17 | 18 | if !cloudflare_auth_config.key.nil? && !cloudflare_auth_config.email.nil? 19 | return({ 20 | 'X-Auth-Key' => cloudflare_auth_config.key, 21 | 'X-Auth-Email' => cloudflare_auth_config.email 22 | }) 23 | end 24 | 25 | unless cloudflare_auth_config.user_service_key.nil? 26 | return({ 27 | 'Authorization' => "Bearer #{cloudflare_auth_config.user_service_key}" 28 | }) 29 | end 30 | 31 | raise( 32 | CloudflairError, 33 | 'Neither email & key nor user_service_key have been defined.' 34 | ) 35 | end 36 | 37 | private_class_method def self.new_faraday_from(config) # rubocop:disable Metrics/AbcSize 38 | Faraday.new(url: config.cloudflare.api_base_url, headers: headers) do |faraday| 39 | faraday.request :json 40 | faraday.response config.faraday.logger if config.faraday.logger 41 | faraday.response :json, content_type: /\bjson$/ 42 | 43 | faraday.adapter config.faraday.adapter || Faraday.default_adapter 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/cloudflair/entity.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cloudflair/communication' 4 | 5 | module Cloudflair 6 | module Entity 7 | include Cloudflair::Communication 8 | 9 | def self.included(other_klass) 10 | other_klass.extend ClassMethods 11 | end 12 | 13 | module ClassMethods 14 | def self.extended(other_klass) 15 | @other_klass = other_klass 16 | end 17 | 18 | def patchable_fields(*fields) 19 | return @patchable_fields if @patchable_fields 20 | 21 | @patchable_fields = 22 | if fields.nil? 23 | [] 24 | elsif fields.is_a?(Array) 25 | fields.map(&:to_s) 26 | else 27 | [fields.to_s] 28 | end 29 | end 30 | 31 | def deletable(deletable = false) 32 | return @deletable unless @deletable.nil? 33 | 34 | @deletable = deletable 35 | end 36 | 37 | def path(path = nil) 38 | return @path if @path 39 | 40 | raise ArgumentError, 'path is not defined' if path.nil? 41 | 42 | @path = path 43 | end 44 | 45 | def object_fields(*fields) 46 | return @object_fields if @object_fields 47 | 48 | @object_fields = 49 | if fields.nil? || fields.empty? 50 | [] 51 | else 52 | fields.map(&:to_s) 53 | end 54 | end 55 | 56 | # allowed values: 57 | # 58 | # array_object_fields :field_a, :field_b, :field_c, 'fieldname_as_string' 59 | # # next is ame as previous 60 | # array_object_fields field_a: nil, field_b: nil, field_c: nil, 'fieldname_as_string': nil 61 | # # next defines the types of the objects 62 | # array_object_fields field_a: Klass, field_b: proc { |data| Klass.new data }, field_c: nil, 'fieldname_as_string' 63 | # 64 | def array_object_fields(*fields_to_class_map) 65 | return @array_object_fields if @array_object_fields 66 | 67 | if fields_to_class_map.nil? || fields_to_class_map.empty? 68 | @array_object_fields = {} 69 | else 70 | fields_map = turn_all_items_into_a_single_hash(fields_to_class_map) 71 | @array_object_fields = fields_map 72 | end 73 | end 74 | 75 | def turn_all_items_into_a_single_hash(fields_to_class_map) 76 | {}.tap do |fields_map| 77 | fields_to_class_map.each do |field_definition| 78 | if field_definition.is_a?(Hash) 79 | fields_to_class_map[0].each do |field, klass_or_proc| 80 | fields_map[field.to_s] = klass_or_proc 81 | end 82 | else 83 | fields_map[field_definition.to_s] = nil 84 | end 85 | end 86 | end 87 | end 88 | end 89 | 90 | def revert 91 | dirty_data.clear 92 | end 93 | 94 | def reload 95 | @data = get 96 | revert 97 | self 98 | end 99 | 100 | def patch 101 | return self if dirty_data.empty? 102 | 103 | @data = response connection.patch path, dirty_data 104 | revert 105 | self 106 | end 107 | 108 | def delete 109 | raise Cloudflair::CloudflairError, "Can't delete unless deletable=true" unless deletable 110 | return self if @deleted 111 | 112 | @data = response connection.delete path 113 | @deleted = true 114 | revert 115 | self 116 | end 117 | 118 | def update(updated_fields) 119 | checked_updated_fields = {} 120 | updated_fields.each do |key, values| 121 | s_key = normalize_accessor key 122 | 123 | checked_updated_fields[s_key] = values if patchable_fields.include? s_key 124 | end 125 | 126 | dirty_data.merge! checked_updated_fields 127 | patch 128 | end 129 | 130 | def method_missing(name_as_symbol, *args, &block) 131 | name = normalize_accessor name_as_symbol 132 | 133 | return data if name_as_symbol == :_raw_data! 134 | 135 | if name.end_with?('=') 136 | if patchable_fields.include?(name[0..-2]) 137 | dirty_data[name[0..-2]] = args[0] 138 | return 139 | end 140 | 141 | super 142 | end 143 | 144 | # allow access to the unmodified data using 'zone.always_string!' or 'zone._name!' 145 | return data[name[0..2]] if name.end_with?('!') && data.key?(name[0..-2]) 146 | return objectify(name) if object_fields.include? name 147 | return arrayify(name, array_object_fields[name]) if array_object_fields.key?(name) 148 | return dirty_data[name] if dirty_data.key?(name) 149 | return data[name] if data.is_a?(Hash) && data.key?(name) 150 | 151 | super 152 | end 153 | 154 | def respond_to_missing?(name_as_symbol, *args) 155 | name = normalize_accessor name_as_symbol 156 | 157 | return true if name_as_symbol == :_raw_data! 158 | return true if name.end_with?('=') && patchable_fields.include?(name[0..-2]) 159 | return true if name.end_with?('!') && data.key?(name[0..-2]) 160 | return true if object_fields.include? name 161 | return true if array_object_fields.key?(name) 162 | return true if dirty_data.key?(name) 163 | return true if data.is_a?(Hash) && data.key?(name) 164 | 165 | super 166 | end 167 | 168 | ## 169 | # :internal: Used to pre-populate an entity 170 | def data=(data) 171 | @data = data 172 | end 173 | 174 | alias get! reload 175 | alias save patch 176 | 177 | private 178 | 179 | def normalize_accessor(symbol_or_string) 180 | always_string = symbol_or_string.to_s 181 | 182 | # allows access to remote data who's name conflicts with pre-defined methods 183 | # e.g. write 'zone._zone_id' instead of 'zone.zone_id' to access the remote value of 'zone_id' 184 | always_string.start_with?('_') ? always_string[1..-1] : always_string 185 | end 186 | 187 | def data 188 | @data ||= get 189 | end 190 | 191 | def get 192 | response connection.get path 193 | end 194 | 195 | def patchable_fields 196 | self.class.patchable_fields 197 | end 198 | 199 | def deletable 200 | self.class.deletable 201 | end 202 | 203 | def object_fields 204 | self.class.object_fields 205 | end 206 | 207 | def array_object_fields 208 | self.class.array_object_fields 209 | end 210 | 211 | def objectify(name) 212 | hash_to_object data[name] 213 | end 214 | 215 | def arrayify(name, klass_or_proc = nil) 216 | data[name].map do |data| 217 | if klass_or_proc.nil? 218 | hash_to_object data 219 | elsif klass_or_proc.is_a? Proc 220 | klass_or_proc.call data 221 | else 222 | klass_or_proc.new data 223 | end 224 | end 225 | end 226 | 227 | def path 228 | return @path if @path 229 | 230 | @path = replace_path_variables_in self.class.path 231 | end 232 | 233 | def replace_path_variables_in(path) 234 | interpreted_path = path.clone 235 | 236 | path.scan(/:([a-zA-Z_][a-zA-Z0-9_]+[!?=]?)/) do |match, *| 237 | interpreted_path = interpreted_path.gsub ":#{match}", send(match).to_s 238 | end 239 | 240 | interpreted_path 241 | end 242 | 243 | def dirty_data 244 | @dirty_data ||= {} 245 | end 246 | end 247 | end 248 | -------------------------------------------------------------------------------- /lib/cloudflair/error/cloudflair_error.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Cloudflair 4 | class CloudflairError < StandardError 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/cloudflair/error/cloudflare_error.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Cloudflair 4 | class CloudflareError < StandardError 5 | attr_reader :cloudflare_errors 6 | 7 | def initialize(cloudflare_errors) 8 | @cloudflare_errors = cloudflare_errors 9 | 10 | super(to_s) 11 | end 12 | 13 | def to_s 14 | if cloudflare_errors.empty? 15 | '[ "An error happened, but no error message/code was given by CloudFlare." (Code: 0000) ]' 16 | else 17 | strings = cloudflare_errors.map { |error| "\"#{error['message']}\" (Code: #{error['code']})" } 18 | "[ #{strings.join ', '} ]" 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/cloudflair/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Cloudflair 4 | end 5 | -------------------------------------------------------------------------------- /spec/cloudflair/api/railguns_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Railguns do 6 | subject { Cloudflair.railgun railgun_identifier } 7 | 8 | let(:railgun_identifier) { 'e928d310693a83094309acf9ead50448' } 9 | let(:response_json) { File.read('spec/cloudflair/fixtures/railgun/railgun.json') } 10 | let(:url) { "/client/v4/railguns/#{railgun_identifier}" } 11 | 12 | before do 13 | faraday_stubs.get(url) do |_env| 14 | [200, { content_type: 'application/json' }, response_json] 15 | end 16 | allow(Faraday).to receive(:new).and_return faraday 17 | end 18 | 19 | it 'knows the given railgun id' do 20 | expect(subject.railgun_id).to eq railgun_identifier 21 | end 22 | 23 | describe 'fetch values' do 24 | it 'fetches the data when asked to' do 25 | expect(faraday).to receive(:get).twice.and_call_original 26 | subject.reload 27 | subject.reload 28 | end 29 | 30 | it 'returns the correct name' do 31 | expect(subject.name).to eq 'My Railgun' 32 | end 33 | 34 | it 'returns the correct enabled status' do 35 | expect(subject.enabled).to be true 36 | end 37 | 38 | it 'returns the amount of zones connected' do 39 | expect(subject.zones_connected).to be 2 40 | end 41 | end 42 | 43 | describe '#update' do 44 | before do 45 | faraday_stubs.patch(url, 'enabled' => false) do |_env| 46 | [200, { content_type: 'application/json' }, response_json] 47 | end 48 | end 49 | 50 | it 'sends PATCH to the server' do 51 | expect(faraday).to receive(:patch).and_call_original 52 | 53 | subject.enabled = false 54 | expect(subject.save).to be subject 55 | # false, because the response is loaded from the server! 56 | # this is a good way to check if the @dirty hash is cleaned 57 | expect(subject.enabled).to be true 58 | end 59 | end 60 | 61 | describe '#delete' do 62 | let(:response_json) { File.read('spec/cloudflair/fixtures/railgun/delete.json') } 63 | 64 | before do 65 | faraday_stubs.delete(url) do |_env| 66 | [200, { content_type: 'application/json' }, response_json] 67 | end 68 | end 69 | 70 | it 'deletes the entity from the server' do 71 | expect(faraday).to receive(:delete).and_call_original 72 | 73 | expect(subject.delete).to be subject 74 | end 75 | 76 | it 'parses the response' do 77 | expect(subject.delete).to be subject 78 | expect(subject.id).to eq railgun_identifier 79 | expect { subject.name }.to raise_error NoMethodError 80 | end 81 | end 82 | 83 | describe '#zones' do 84 | subject { Cloudflair.railgun(railgun_identifier).zones } 85 | 86 | let(:url) { "/client/v4/railguns/#{railgun_identifier}/zones" } 87 | let(:response_json) { File.read('spec/cloudflair/fixtures/railgun/railgun_zones.json') } 88 | 89 | it 'fetches the associated zones' do 90 | expect(faraday).to receive(:get).and_call_original 91 | 92 | expect(subject).not_to be_nil 93 | expect(subject).to be_an Array 94 | end 95 | 96 | it 'parses the correct values' do 97 | expect(subject.length).to be 1 98 | expect(subject[0].id).to eq '023e105f4ecef8ad9ca31a8372d0c353' 99 | expect(subject[0].name).to eq 'example.com' 100 | expect(subject[0].original_name_servers).to be_an Array 101 | expect(subject[0].original_name_servers.length).to be 2 102 | end 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/analytics_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::DnsRecord do 6 | subject(:analytics) { Cloudflair.zone(zone_identifier).analytics } 7 | 8 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 9 | 10 | before do 11 | faraday_stubs.get(url) do |_env| 12 | [200, { content_type: 'application/json' }, response_json] 13 | end 14 | allow(Faraday).to receive(:new).and_return faraday 15 | end 16 | 17 | describe '#dashboard' do 18 | subject { analytics.dashboard } 19 | 20 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/analytics_dashboard.json') } 21 | let(:url) { "/client/v4/zones/#{zone_identifier}/analytics/dashboard" } 22 | 23 | it 'fetches the values' do 24 | expect(faraday).to receive(:get).and_call_original 25 | 26 | expect(subject).not_to be_nil 27 | expect(subject).not_to be_a Hash 28 | end 29 | 30 | it 'does not cache the response' do 31 | expect(faraday).to receive(:get).twice.and_call_original 32 | 33 | a = analytics.dashboard 34 | b = analytics.dashboard 35 | 36 | expect(a).not_to be_nil 37 | expect(b).not_to be_nil 38 | 39 | expect(a).not_to be b 40 | expect(b).not_to be a 41 | end 42 | 43 | it 'returns the actual values' do 44 | expect(subject.totals).not_to be_nil 45 | expect(subject.totals).to be_a Hash 46 | expect(subject.totals['requests']['all']).to be 1_234_085_328 47 | expect(subject.timeseries).not_to be_nil 48 | expect(subject.timeseries.length).to be 1 49 | end 50 | end 51 | 52 | describe '#colos' do 53 | subject { analytics.colos } 54 | 55 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/analytics_colos.json') } 56 | let(:url) { "/client/v4/zones/#{zone_identifier}/analytics/colos" } 57 | 58 | it 'fetches the values' do 59 | expect(faraday).to receive(:get).and_call_original 60 | 61 | expect(subject).not_to be_nil 62 | expect(subject).to be_an Array 63 | end 64 | 65 | it 'does not cache the response' do 66 | expect(faraday).to receive(:get).twice.and_call_original 67 | 68 | a = analytics.colos 69 | b = analytics.colos 70 | 71 | expect(a).not_to be_nil 72 | expect(b).not_to be_nil 73 | 74 | expect(a).not_to be b 75 | expect(b).not_to be a 76 | end 77 | 78 | it 'returns the actual values' do 79 | expect(subject.length).to be 1 80 | expect(subject[0]).not_to be_a Hash 81 | expect(subject[0].colo_id).to eq 'SFO' 82 | expect(subject[0].timeseries).not_to be_nil 83 | expect(subject[0].timeseries.length).to be 1 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/available_plan_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::AvailablePlan do 6 | subject { Cloudflair.zone(zone_identifier).available_plan(plan_identifier) } 7 | 8 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 9 | let(:plan_identifier) { 'e592fd9519420ba7405e1307bff33214' } 10 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/plan.json') } 11 | let(:url) { "/client/v4/zones/#{zone_identifier}/available_plans/#{plan_identifier}" } 12 | 13 | before do 14 | faraday_stubs.get(url) do |_env| 15 | [200, { content_type: 'application/json' }, response_json] 16 | end 17 | allow(Faraday).to receive(:new).and_return faraday 18 | end 19 | 20 | it 'loads the data on demand and caches' do 21 | expect(faraday).to receive(:get).once.and_call_original 22 | 23 | expect(subject.name).to eq 'Pro Plan' 24 | expect(subject.price).to be 20 25 | expect(subject.can_subscribe).to be true 26 | end 27 | 28 | it 'reloads the AvailablePlan on request' do 29 | expect(faraday).to receive(:get).twice.and_call_original 30 | 31 | expect(subject.reload).to be subject 32 | expect(subject.reload).to be subject 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/available_rate_plan_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::AvailableRatePlan do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/available_rate_plans.json') } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/available_rate_plans" } 9 | let(:subject) { described_class.new zone_identifier } 10 | 11 | before do 12 | faraday_stubs.get(url) do |_env| 13 | [200, { content_type: 'application/json' }, response_json] 14 | end 15 | allow(Faraday).to receive(:new).and_return faraday 16 | end 17 | 18 | it 'parses the simple values' do 19 | expect(faraday).to receive(:get).once.and_call_original 20 | 21 | expect(subject.id).to eq 'free' 22 | expect(subject.name).to eq 'Free Plan' 23 | expect(subject.currency).to eq 'USD' 24 | expect(subject.duration).to be 1 25 | expect(subject.frequency).to eq 'monthly' 26 | end 27 | 28 | it 'parses the components array' do 29 | components = subject.components 30 | 31 | expect(components).to be_a Array 32 | expect(components.length).to be 1 33 | 34 | component = components[0] 35 | expect(component).not_to be_a Hash 36 | expect(component.name).to eq 'page_rules' 37 | expect(component.default).to be 5 38 | expect(component.unit_price).to be 1 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/custom_hostname_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::CustomHostname do 6 | subject { Cloudflair.zone(zone_identifier).custom_hostname(hostname_identifier) } 7 | 8 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 9 | let(:hostname_identifier) { '0d89c70d-ad9f-4843-b99f-6cc0252067e9' } 10 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/custom_hostname.json') } 11 | let(:url) { "/client/v4/zones/#{zone_identifier}/custom_hostnames/#{hostname_identifier}" } 12 | 13 | before do 14 | faraday_stubs.get(url) do |_env| 15 | [200, { content_type: 'application/json' }, response_json] 16 | end 17 | allow(Faraday).to receive(:new).and_return faraday 18 | end 19 | 20 | it 'loads the data on demand and caches' do 21 | expect(faraday).to receive(:get).once.and_call_original 22 | 23 | expect(subject.id).to eq hostname_identifier 24 | expect(subject.hostname).to eq 'app.example.com' 25 | end 26 | 27 | it 'reloads the AvailablePlan on request' do 28 | expect(faraday).to receive(:get).twice.and_call_original 29 | 30 | expect(subject.reload).to be subject 31 | expect(subject.reload).to be subject 32 | end 33 | 34 | describe '#delete' do 35 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/custom_hostname_deleted.json') } 36 | 37 | before do 38 | faraday_stubs.delete(url) do |_env| 39 | [200, { content_type: 'application/json' }, response_json] 40 | end 41 | end 42 | 43 | it 'performs the delete' do 44 | expect(faraday).to receive(:delete).once.and_call_original 45 | 46 | subject.delete 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/dns_record_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::DnsRecord do 6 | subject { Cloudflair.zone(zone_identifier).dns_record(record_identifier) } 7 | 8 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 9 | let(:record_identifier) { '372e67954025e0ba6aaa6d586b9e0b59' } 10 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/dns_record.json') } 11 | let(:url) { "/client/v4/zones/#{zone_identifier}/dns_records/#{record_identifier}" } 12 | 13 | before do 14 | faraday_stubs.get(url) do |_env| 15 | [200, { content_type: 'application/json' }, response_json] 16 | end 17 | allow(Faraday).to receive(:new).and_return faraday 18 | end 19 | 20 | it 'loads the data on demand and caches' do 21 | expect(faraday).to receive(:get).once.and_call_original 22 | 23 | expect(subject.id).to eq record_identifier 24 | expect(subject.name).to eq 'example.com' 25 | expect(subject.type).to eq 'A' 26 | expect(subject.content).to eq '1.2.3.4' 27 | expect(subject.ttl).to be 120 28 | expect(subject.locked).to be false 29 | end 30 | 31 | it 'reloads the AvailablePlan on request' do 32 | expect(faraday).to receive(:get).twice.and_call_original 33 | 34 | expect(subject.reload).to be subject 35 | expect(subject.reload).to be subject 36 | end 37 | 38 | describe '#delete' do 39 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/dns_record_deleted.json') } 40 | 41 | before do 42 | faraday_stubs.delete(url) do |_env| 43 | [200, { content_type: 'application/json' }, response_json] 44 | end 45 | end 46 | 47 | it 'performs the delete' do 48 | expect(faraday).to receive(:delete).once.and_call_original 49 | 50 | subject.delete 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/purge_cache_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'faraday/detailed_logger' 5 | 6 | describe Cloudflair::PurgeCache do 7 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 8 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/purge_cache.json') } 9 | let(:url) { "/client/v4/zones/#{zone_identifier}/purge_cache" } 10 | let(:subject) { Cloudflair.zone(zone_identifier).purge_cache } 11 | 12 | before do 13 | allow(Faraday).to receive(:new).and_return faraday 14 | end 15 | 16 | describe '#everything' do 17 | before do 18 | faraday_stubs.post(url) do |env| 19 | expect(env.body).to eq(purge_everything: true) 20 | 21 | [200, { content_type: 'application/json' }, response_json] 22 | end 23 | end 24 | 25 | it 'deletes all files' do 26 | expect(faraday).to receive(:post).and_call_original 27 | 28 | expect(subject.everything(true)).to be subject 29 | end 30 | 31 | it 'is repeatedly executed' do 32 | expect(faraday).to receive(:post).twice.and_call_original 33 | 34 | expect(subject.everything(true)).to be subject 35 | expect(subject.everything(true)).to be subject 36 | end 37 | 38 | context 'invalid response' do 39 | let(:response_json) { '{"foo":"bar"}' } 40 | 41 | it 'raises an error' do 42 | expect { subject.everything(true) }.to raise_error Cloudflair::CloudflairError 43 | end 44 | end 45 | end 46 | 47 | describe '#selective' do 48 | let(:selective_list) { { tags: ['hello'], files: ['https://foo.bar/index.html'] } } 49 | 50 | before do 51 | faraday_stubs.post(url) do |env| 52 | expect(env.body).to eq(selective_list) 53 | 54 | [200, { content_type: 'application/json' }, response_json] 55 | end 56 | end 57 | 58 | it 'deletes all files' do 59 | expect(faraday).to receive(:post).and_call_original 60 | 61 | expect(subject.selective(selective_list)).to be subject 62 | end 63 | 64 | it 'is repeatedly executed' do 65 | expect(faraday).to receive(:post).twice.and_call_original 66 | 67 | expect(subject.selective(selective_list)).to be subject 68 | expect(subject.selective(selective_list)).to be subject 69 | end 70 | 71 | context 'invalid response' do 72 | let(:response_json) { '{"foo":"bar"}' } 73 | 74 | it 'raises an error' do 75 | expect { subject.selective(selective_list) }.to raise_error Cloudflair::CloudflairError 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/railgun_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Railgun do 6 | subject(:railgun) { Cloudflair.zone(zone_identifier).railgun(railgun_identifier) } 7 | 8 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 9 | let(:railgun_identifier) { 'e928d310693a83094309acf9ead50448' } 10 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/railgun.json') } 11 | let(:url) { "/client/v4/zones/#{zone_identifier}/railguns/#{railgun_identifier}" } 12 | 13 | before do 14 | faraday_stubs.get(url) do |_env| 15 | [200, { content_type: 'application/json' }, response_json] 16 | end 17 | allow(Faraday).to receive(:new).and_return faraday 18 | end 19 | 20 | it 'loads the data on demand and caches' do 21 | expect(faraday).to receive(:get).once.and_call_original 22 | 23 | expect(subject.id).to eq railgun_identifier 24 | expect(subject.name).to eq 'My Railgun' 25 | expect(subject.enabled).to be true 26 | expect(subject.connected).to be true 27 | end 28 | 29 | describe '#reload' do 30 | it 'reloads the AvailablePlan on request' do 31 | expect(faraday).to receive(:get).twice.and_call_original 32 | 33 | expect(subject.reload).to be subject 34 | expect(subject.reload).to be subject 35 | end 36 | end 37 | 38 | describe '#diagnose' do 39 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/railgun_diagnose.json') } 40 | let(:url) { "/client/v4/zones/#{zone_identifier}/railguns/#{railgun_identifier}/diagnose" } 41 | let(:railgun) { subject.diagnose } 42 | 43 | it 'calls the diagnose endpoint' do 44 | expect(faraday).to receive(:get).and_call_original 45 | 46 | expect(railgun).not_to be_nil 47 | expect(railgun).not_to be_a Hash 48 | end 49 | 50 | it 'returns the right values' do 51 | expect(railgun._method).to eq 'GET' 52 | expect(railgun.host_name).to eq 'www.example.com' 53 | expect(railgun.connection_close).to be false 54 | expect(railgun.cf_wan_error).to be_nil 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/advanced_ddos_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::AdvancedDdos do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'advanced_ddos' } 12 | let(:value) { 'on' } 13 | let(:new_value) { 'off' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be false 31 | end 32 | end 33 | 34 | # non-standard 35 | describe 'put values' do 36 | it 'does not save the value' do 37 | expect(faraday).not_to receive(:patch) 38 | 39 | expect { subject.value = new_value }.to raise_error NoMethodError 40 | 41 | subject.save 42 | 43 | expect(subject.value).to eq value 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/always_online_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::AlwaysOnline do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'always_online' } 12 | let(:value) { 'on' } 13 | let(:new_value) { 'off' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/browser_cache_ttl_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::BrowserCacheTtl do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'browser_cache_ttl' } 12 | let(:value) { 14_400 } 13 | let(:new_value) { 7200 } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to be value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/browser_check_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::BrowserCheck do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'browser_check' } 12 | let(:value) { 'on' } 13 | let(:new_value) { 'off' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/cache_level_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::CacheLevel do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'cache_level' } 12 | let(:value) { 'aggressive' } 13 | let(:new_value) { 'simplified' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/challenge_ttl_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::ChallengeTtl do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'challenge_ttl' } 12 | let(:value) { 1800 } 13 | let(:new_value) { 605_800 } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/development_mode_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::DevelopmentMode do 6 | subject(:development_mode) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 7 | 8 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 9 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 10 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 11 | 12 | let(:setting_identifier) { 'development_mode' } 13 | let(:value) { 'off' } 14 | let(:new_value) { 'on' } 15 | 16 | before do 17 | faraday_stubs.get(url) do |_env| 18 | [200, { content_type: 'application/json' }, response_json] 19 | end 20 | allow(Faraday).to receive(:new).and_return faraday 21 | end 22 | 23 | it 'returns the correct zone_id' do 24 | expect(subject.zone_id).to eq zone_identifier 25 | end 26 | 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.id).to eq setting_identifier 30 | expect(subject.value).to eq value 31 | expect(subject.editable).to be true 32 | end 33 | end 34 | 35 | describe 'put values' do 36 | before do 37 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 38 | [200, { content_type: 'application/json' }, response_json] 39 | end 40 | end 41 | 42 | it 'saves the values' do 43 | expect(faraday).to receive(:patch).and_call_original 44 | subject.value = new_value 45 | subject.save 46 | 47 | expect(subject.value).to eq value 48 | end 49 | end 50 | 51 | describe '#time_remaining' do 52 | subject { development_mode.time_remaining } 53 | 54 | context 'when the development mode was on at least once' do 55 | it { is_expected.to eq 3600 } 56 | end 57 | 58 | context 'when the development mode was never on' do 59 | let(:response_json) do 60 | File.read('spec/cloudflair/fixtures/zone/settings/development_mode_without_time_remaining.json') 61 | end 62 | 63 | it { is_expected.to eq 0 } 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/email_obfuscation_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::EmailObfuscation do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'email_obfuscation' } 12 | let(:value) { 'on' } 13 | let(:new_value) { 'off' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/hotlink_protection_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::HotlinkProtection do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'hotlink_protection' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/ip_geolocation_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::IpGeolocation do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'ip_geolocation' } 12 | let(:value) { 'on' } 13 | let(:new_value) { 'off' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/ipv6_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Ipv6 do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'ipv6' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/minify_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Minify do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'minify' } 12 | let(:value) { { 'css' => 'off', 'html' => 'off', 'js' => 'off' } } 13 | let(:new_value) { { 'css' => 'on', 'html' => 'on', 'js' => 'off' } } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/mirage_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Mirage do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'mirage' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/mobile_redirect_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::MobileRedirect do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'mobile_redirect' } 12 | let(:value) { { 'status' => 'off', 'mobile_subdomain' => 'm', 'strip_uri' => false } } 13 | let(:new_value) { { 'status' => 'on', 'mobile_subdomain' => 'i', 'strip_uri' => true } } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/origin_error_page_pass_thru_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::OriginErrorPagePassThru do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'origin_error_page_pass_thru' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | # non-standard (has no .id) 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.value).to eq value 30 | end 31 | end 32 | 33 | # non-standard 34 | describe 'put values' do 35 | it 'does not save the value' do 36 | expect(faraday).not_to receive(:patch) 37 | 38 | expect { subject.value = new_value }.to raise_error NoMethodError 39 | 40 | subject.save 41 | 42 | expect(subject.value).to eq value 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/polish_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Polish do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'polish' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/prefetch_preload_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::PrefetchPreload do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'prefetch_preload' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | # non-standard (has no .id) 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.value).to eq value 30 | end 31 | end 32 | 33 | describe 'put values' do 34 | before do 35 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 36 | [200, { content_type: 'application/json' }, response_json] 37 | end 38 | end 39 | 40 | it 'saves the values' do 41 | expect(faraday).to receive(:patch).and_call_original 42 | subject.value = new_value 43 | subject.save 44 | 45 | expect(subject.value).to eq value 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/response_buffering_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::ResponseBuffering do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'response_buffering' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | # non-standard (has no .id) 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.value).to eq value 30 | end 31 | end 32 | 33 | describe 'put values' do 34 | before do 35 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 36 | [200, { content_type: 'application/json' }, response_json] 37 | end 38 | end 39 | 40 | it 'saves the values' do 41 | expect(faraday).to receive(:patch).and_call_original 42 | subject.value = new_value 43 | subject.save 44 | 45 | expect(subject.value).to eq value 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/rocket_loader_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::RocketLoader do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'rocket_loader' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'manual' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/security_header_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::SecurityHeader do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'security_header' } 12 | let(:value) do 13 | { 14 | 'strict_transport_security' => 15 | { 16 | 'enabled' => true, 17 | 'max_age' => 86_400, 18 | 'include_subdomains' => true, 19 | 'nosniff' => true 20 | } 21 | } 22 | end 23 | let(:new_value) { { 'strict_transport_security' => { 'enabled' => false } } } 24 | 25 | before do 26 | faraday_stubs.get(url) do |_env| 27 | [200, { content_type: 'application/json' }, response_json] 28 | end 29 | allow(Faraday).to receive(:new).and_return faraday 30 | end 31 | 32 | it 'returns the correct zone_id' do 33 | expect(subject.zone_id).to eq zone_identifier 34 | end 35 | 36 | describe 'fetch values' do 37 | it 'fetches relevant values' do 38 | expect(subject.id).to eq setting_identifier 39 | expect(subject.value).to eq value 40 | expect(subject.editable).to be true 41 | end 42 | end 43 | 44 | describe 'put values' do 45 | before do 46 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 47 | [200, { content_type: 'application/json' }, response_json] 48 | end 49 | end 50 | 51 | it 'saves the values' do 52 | expect(faraday).to receive(:patch).and_call_original 53 | subject.value = new_value 54 | subject.save 55 | 56 | expect(subject.value).to eq value 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/security_level_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::SecurityLevel do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'security_level' } 12 | let(:value) { 'medium' } 13 | let(:new_value) { 'high' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/server_side_exclude_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::ServerSideExclude do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'server_side_exclude' } 12 | let(:value) { 'on' } 13 | let(:new_value) { 'off' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/sort_query_string_for_cache_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::SortQueryStringForCache do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'sort_query_string_for_cache' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | # non-standard (has no .id) 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.value).to eq value 30 | end 31 | end 32 | 33 | # non-standard 34 | describe 'put values' do 35 | it 'does not save the value' do 36 | expect(faraday).not_to receive(:patch) 37 | 38 | expect { subject.value = new_value }.to raise_error NoMethodError 39 | 40 | subject.save 41 | 42 | expect(subject.value).to eq value 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/ssl_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Ssl do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'ssl' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/tls_1_2_only_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Tls12Only do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'tls_1_2_only' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | # non standard 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.value).to eq value 30 | end 31 | end 32 | 33 | describe 'put values' do 34 | before do 35 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 36 | [200, { content_type: 'application/json' }, response_json] 37 | end 38 | end 39 | 40 | it 'saves the values' do 41 | expect(faraday).to receive(:patch).and_call_original 42 | subject.value = new_value 43 | subject.save 44 | 45 | expect(subject.value).to eq value 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/tls_1_3_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Tls13 do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'tls_1_3' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | # non standard 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.value).to eq value 30 | end 31 | end 32 | 33 | describe 'put values' do 34 | before do 35 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 36 | [200, { content_type: 'application/json' }, response_json] 37 | end 38 | end 39 | 40 | it 'saves the values' do 41 | expect(faraday).to receive(:patch).and_call_original 42 | subject.value = new_value 43 | subject.save 44 | 45 | expect(subject.value).to eq value 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/tls_client_auth_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::TlsClientAuth do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'tls_client_auth' } 12 | let(:value) { 'on' } 13 | let(:new_value) { 'off' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/true_client_ip_header_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::TrueClientIpHeader do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'true_client_ip_header' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | # non-standard (has no .id) 27 | describe 'fetch values' do 28 | it 'fetches relevant values' do 29 | expect(subject.value).to eq value 30 | end 31 | end 32 | 33 | describe 'put values' do 34 | before do 35 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 36 | [200, { content_type: 'application/json' }, response_json] 37 | end 38 | end 39 | 40 | it 'saves the values' do 41 | expect(faraday).to receive(:patch).and_call_original 42 | subject.value = new_value 43 | subject.save 44 | 45 | expect(subject.value).to eq value 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/waf_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Waf do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'waf' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings/websockets_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Ssl do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | let(:response_json) { File.read("spec/cloudflair/fixtures/zone/settings/#{setting_identifier}.json") } 8 | let(:url) { "/client/v4/zones/#{zone_identifier}/settings/#{setting_identifier}" } 9 | let(:subject) { Cloudflair.zone(zone_identifier).settings.public_send setting_identifier } 10 | 11 | let(:setting_identifier) { 'websockets' } 12 | let(:value) { 'off' } 13 | let(:new_value) { 'on' } 14 | 15 | before do 16 | faraday_stubs.get(url) do |_env| 17 | [200, { content_type: 'application/json' }, response_json] 18 | end 19 | allow(Faraday).to receive(:new).and_return faraday 20 | end 21 | 22 | it 'returns the correct zone_id' do 23 | expect(subject.zone_id).to eq zone_identifier 24 | end 25 | 26 | describe 'fetch values' do 27 | it 'fetches relevant values' do 28 | expect(subject.id).to eq setting_identifier 29 | expect(subject.value).to eq value 30 | expect(subject.editable).to be true 31 | end 32 | end 33 | 34 | describe 'put values' do 35 | before do 36 | faraday_stubs.patch(url, 'value' => new_value) do |_env| 37 | [200, { content_type: 'application/json' }, response_json] 38 | end 39 | end 40 | 41 | it 'saves the values' do 42 | expect(faraday).to receive(:patch).and_call_original 43 | subject.value = new_value 44 | subject.save 45 | 46 | expect(subject.value).to eq value 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone/settings_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Settings do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | 8 | let(:subject) { Cloudflair.zone(zone_identifier).settings } 9 | 10 | it 'returns the correct zone_id' do 11 | expect(subject.zone_id).to eq zone_identifier 12 | end 13 | 14 | { 15 | always_online: Cloudflair::AlwaysOnline, 16 | advanced_ddos: Cloudflair::AdvancedDdos, 17 | browser_cache_ttl: Cloudflair::BrowserCacheTtl, 18 | browser_check: Cloudflair::BrowserCheck, 19 | cache_level: Cloudflair::CacheLevel, 20 | challenge_ttl: Cloudflair::ChallengeTtl, 21 | development_mode: Cloudflair::DevelopmentMode, 22 | email_obfuscation: Cloudflair::EmailObfuscation, 23 | hotlink_protection: Cloudflair::HotlinkProtection, 24 | ip_geolocation: Cloudflair::IpGeolocation, 25 | ipv6: Cloudflair::Ipv6, 26 | minify: Cloudflair::Minify, 27 | mirage: Cloudflair::Mirage, 28 | mobile_redirect: Cloudflair::MobileRedirect, 29 | origin_error_page_pass_thru: Cloudflair::OriginErrorPagePassThru, 30 | polish: Cloudflair::Polish, 31 | prefetch_preload: Cloudflair::PrefetchPreload, 32 | response_buffering: Cloudflair::ResponseBuffering, 33 | rocket_loader: Cloudflair::RocketLoader, 34 | security_header: Cloudflair::SecurityHeader, 35 | security_level: Cloudflair::SecurityLevel, 36 | server_side_exclude: Cloudflair::ServerSideExclude, 37 | sort_query_string_for_cache: Cloudflair::SortQueryStringForCache, 38 | ssl: Cloudflair::Ssl, 39 | tls_client_auth: Cloudflair::TlsClientAuth, 40 | tls_1_2_only: Cloudflair::Tls12Only, 41 | tls_1_3: Cloudflair::Tls13, 42 | true_client_ip_header: Cloudflair::TrueClientIpHeader, 43 | waf: Cloudflair::Waf, 44 | websockets: Cloudflair::Websockets 45 | }.each do |method, klass| 46 | it "returns an initialized #{method} object" do 47 | expect(subject.public_send(method)).to be_a klass 48 | expect(subject.public_send(method).zone_id).to eq zone_identifier 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone__available_plans_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Zone, 'available_plans things' do 6 | subject { Cloudflair.zone zone_identifier } 7 | 8 | before do 9 | allow(Faraday).to receive(:new).and_return faraday 10 | end 11 | 12 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 13 | let(:url) { "/client/v4/zones/#{zone_identifier}/dns_records" } 14 | 15 | describe '#available_plan' do 16 | it 'returns an AvailablePlan instance' do 17 | expect(subject.available_plan('abcdef')).to be_a Cloudflair::AvailablePlan 18 | end 19 | end 20 | 21 | describe '#available_plans' do 22 | let(:url) { "/client/v4/zones/#{zone_identifier}/available_plans" } 23 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/plans.json') } 24 | let(:available_plans) { subject.available_plans } 25 | 26 | before do 27 | faraday_stubs.get(url) do |_env| 28 | [200, { content_type: 'application/json' }, response_json] 29 | end 30 | end 31 | 32 | it 'calls the other url' do 33 | expect(faraday).to receive(:get).once.and_call_original 34 | 35 | available_plans 36 | end 37 | 38 | it 'returns the correct types' do 39 | expect(available_plans).to be_a Array 40 | available_plans.each do |plan| 41 | expect(plan).to be_a Cloudflair::AvailablePlan 42 | end 43 | end 44 | 45 | it 'returns the correct amount' do 46 | expect(available_plans.length).to be 1 47 | end 48 | 49 | it 'returns the correct values' do 50 | plan = available_plans[0] 51 | expect(plan.id).to eq 'e592fd9519420ba7405e1307bff33214' 52 | expect(plan.price).to be 20 53 | expect(plan.is_subscribed).to be true 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone__custom_hostnames_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Zone, 'custom_hostname things' do 6 | subject(:zone) { Cloudflair.zone zone_identifier } 7 | 8 | before do 9 | allow(Faraday).to receive(:new).and_return faraday 10 | end 11 | 12 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 13 | let(:url) { "/client/v4/zones/#{zone_identifier}/custom_hostnames" } 14 | 15 | describe '#custom_hostname' do 16 | it 'returns a Custom Hostname instance' do 17 | expect(subject.custom_hostname('abcdef')).to be_a Cloudflair::CustomHostname 18 | end 19 | end 20 | 21 | describe '#new_custom_hostname=' do 22 | let(:new_custom_hostname_data) { { hostname: 'app.example.com', ssl: { method: 'http', type: 'dv', settings: { http2: 'on', min_tls_version: '1.2', tls_1_3: 'on', ciphers: %w[ECDHE-RSA-AES128-GCM-SHA256 AES128-SHA] } } } } 23 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/custom_hostname.json') } 24 | let(:the_new_custom_hostname) { subject.new_custom_hostname(new_custom_hostname_data) } 25 | 26 | before do 27 | faraday_stubs.post(url, new_custom_hostname_data) do |_env| 28 | [200, { content_type: 'application/json' }, response_json] 29 | end 30 | end 31 | 32 | it 'returns a new CustomHostname instance' do 33 | expect(faraday).to receive(:post).and_call_original 34 | 35 | expect(the_new_custom_hostname).to be_a Cloudflair::CustomHostname 36 | end 37 | 38 | it 'prepopulates the returned CustomHostname instance' do 39 | expect(faraday).not_to receive(:get) 40 | 41 | expect(the_new_custom_hostname.id).to eq('0d89c70d-ad9f-4843-b99f-6cc0252067e9') 42 | expect(the_new_custom_hostname.hostname).to eq('app.example.com') 43 | expect(the_new_custom_hostname.ssl['type']).to eq('dv') 44 | end 45 | end 46 | 47 | describe '#custom_hostnames' do 48 | subject { zone.custom_hostnames } 49 | 50 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/custom_hostnames.json') } 51 | 52 | before do 53 | faraday_stubs.get(url) do |_env| 54 | [200, { content_type: 'application/json' }, response_json] 55 | end 56 | end 57 | 58 | it 'calls the other url' do 59 | expect(faraday).to receive(:get).once.and_call_original 60 | 61 | subject 62 | end 63 | 64 | it 'returns the correct types' do 65 | expect(subject).to be_a Array 66 | subject.each do |plan| 67 | expect(plan).to be_a Cloudflair::CustomHostname 68 | end 69 | end 70 | 71 | it 'returns the correct amount' do 72 | expect(subject.length).to be 1 73 | end 74 | 75 | it 'returns the correct values' do 76 | custom_hostname = subject[0] 77 | expect(custom_hostname.id).to eq '0d89c70d-ad9f-4843-b99f-6cc0252067e9' 78 | expect(custom_hostname.hostname).to eq 'app.example.com' 79 | expect(custom_hostname.ssl['type']).to eq 'dv' 80 | end 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone__dns_records_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Zone, 'dns_record things' do 6 | subject(:zone) { Cloudflair.zone zone_identifier } 7 | 8 | before do 9 | allow(Faraday).to receive(:new).and_return faraday 10 | end 11 | 12 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 13 | let(:url) { "/client/v4/zones/#{zone_identifier}/dns_records" } 14 | 15 | describe '#dns_record' do 16 | it 'returns a DnsRecord instance' do 17 | expect(subject.dns_record('abcdef')).to be_a Cloudflair::DnsRecord 18 | end 19 | end 20 | 21 | describe '#new_dns_record=' do 22 | let(:new_dns_record_data) { { type: 'A', name: 'example.com', content: '127.0.0.1' } } 23 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/dns_record.json') } 24 | let(:the_new_dns_record) { subject.new_dns_record(new_dns_record_data) } 25 | 26 | before do 27 | faraday_stubs.post(url, new_dns_record_data) do |_env| 28 | [200, { content_type: 'application/json' }, response_json] 29 | end 30 | end 31 | 32 | it 'returns a new DnsRecord instance' do 33 | expect(faraday).to receive(:post).and_call_original 34 | 35 | expect(the_new_dns_record).to be_a Cloudflair::DnsRecord 36 | end 37 | 38 | it 'prepopulates the returned DnsRecord instance' do 39 | expect(faraday).not_to receive(:get) 40 | 41 | expect(the_new_dns_record.id).to eq('372e67954025e0ba6aaa6d586b9e0b59') 42 | expect(the_new_dns_record.ttl).to be 120 43 | expect(the_new_dns_record.locked).to be false 44 | end 45 | end 46 | 47 | describe '#dns_records' do 48 | subject { zone.dns_records } 49 | 50 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/dns_records.json') } 51 | 52 | before do 53 | faraday_stubs.get(url) do |_env| 54 | [200, { content_type: 'application/json' }, response_json] 55 | end 56 | end 57 | 58 | it 'calls the other url' do 59 | expect(faraday).to receive(:get).once.and_call_original 60 | 61 | subject 62 | end 63 | 64 | it 'returns the correct types' do 65 | expect(subject).to be_a Array 66 | subject.each do |plan| 67 | expect(plan).to be_a Cloudflair::DnsRecord 68 | end 69 | end 70 | 71 | it 'returns the correct amount' do 72 | expect(subject.length).to be 1 73 | end 74 | 75 | it 'returns the correct values' do 76 | dns_record = subject[0] 77 | expect(dns_record.id).to eq '372e67954025e0ba6aaa6d586b9e0b59' 78 | expect(dns_record.type).to eq 'A' 79 | expect(dns_record.content).to eq '1.2.3.4' 80 | expect(dns_record.proxiable).to be true 81 | expect(dns_record.ttl).to be 120 82 | expect(dns_record.data).to be_a Hash 83 | expect(dns_record.data.empty?).to be true 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone__railguns_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Zone, 'railguns things' do 6 | subject(:zone) { Cloudflair.zone zone_identifier } 7 | 8 | before do 9 | allow(Faraday).to receive(:new).and_return faraday 10 | faraday_stubs.get(url) do |_env| 11 | [200, { content_type: 'application/json' }, response_json] 12 | end 13 | end 14 | 15 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 16 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/railguns.json') } 17 | let(:url) { "/client/v4/zones/#{zone_identifier}/railguns" } 18 | 19 | describe '#railgun' do 20 | it 'returns a DnsRecord instance' do 21 | expect(subject.railgun('abcdef')).to be_a Cloudflair::Railgun 22 | end 23 | end 24 | 25 | describe '#railguns' do 26 | subject { zone.railguns } 27 | 28 | it 'calls the other url' do 29 | expect(faraday).to receive(:get).once.and_call_original 30 | 31 | subject 32 | end 33 | 34 | it 'returns the correct types' do 35 | expect(subject).to be_a Array 36 | subject.each do |item| 37 | expect(item).to be_a Cloudflair::Railgun 38 | end 39 | end 40 | 41 | it 'returns the correct amount' do 42 | expect(subject.length).to be 1 43 | end 44 | 45 | it 'returns the correct values' do 46 | dns_record = subject[0] 47 | expect(dns_record.id).to eq 'e928d310693a83094309acf9ead50448' 48 | expect(dns_record.name).to eq 'My Railgun' 49 | expect(dns_record.enabled).to be true 50 | expect(dns_record.connected).to be true 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /spec/cloudflair/api/zone_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Zone do 6 | subject { Cloudflair.zone zone_identifier } 7 | 8 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 9 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/details.json') } 10 | let(:url) { "/client/v4/zones/#{zone_identifier}" } 11 | 12 | before do 13 | faraday_stubs.get(url) do |_env| 14 | [200, { content_type: 'application/json' }, response_json] 15 | end 16 | allow(Faraday).to receive(:new).and_return faraday 17 | end 18 | 19 | it 'knows the given zone id' do 20 | expect(subject.zone_id).to eq zone_identifier 21 | end 22 | 23 | it 'returns the settings instance' do 24 | expect(subject.settings).to be_a Cloudflair::Settings 25 | end 26 | 27 | it 'returns the PurgeCache instance' do 28 | expect(subject.purge_cache).to be_a Cloudflair::PurgeCache 29 | end 30 | 31 | it 'returns the Analytics instance' do 32 | expect(subject.analytics).to be_a Cloudflair::Analytics 33 | end 34 | 35 | describe 'fetch values' do 36 | it 'fetches the data when asked to' do 37 | expect(faraday).to receive(:get).twice.and_call_original 38 | subject.reload 39 | subject.reload 40 | end 41 | 42 | it 'returns itself when get!ing' do 43 | expect(subject.reload).to be subject 44 | end 45 | 46 | it 'returns the correct name' do 47 | expect(subject.name).to eq 'example.com' 48 | end 49 | 50 | it 'returns the correct name' do 51 | expect(subject._name).to eq 'example.com' 52 | end 53 | 54 | it 'returns the correct paused status' do 55 | expect(subject.paused).to be false 56 | end 57 | 58 | it 'returns the remaining development mode time' do 59 | expect(subject.development_mode).to eq 7200 60 | end 61 | 62 | context '#plan' do 63 | it 'returns the plan as actual object' do 64 | expect(subject.plan).not_to be_a Hash 65 | end 66 | 67 | it 'passes all the values to the plan object' do 68 | expect(faraday).to receive(:get).once.and_call_original 69 | 70 | expect(subject.plan.id).to eq 'e592fd9519420ba7405e1307bff33214' 71 | end 72 | 73 | it 'is possible to reload the plan object' do 74 | expect(faraday).to receive(:get).once.and_call_original 75 | 76 | expect(subject.plan.name).to eq 'Pro Plan' 77 | end 78 | end 79 | 80 | context '#plan_pending' do 81 | it 'returns the pending plan as actual object' do 82 | expect(subject.plan_pending).not_to be_a Hash 83 | end 84 | 85 | it 'passes all the values to the plan_pending object' do 86 | expect(faraday).to receive(:get).once.and_call_original 87 | 88 | expect(subject.plan_pending.id).to eq 'e592fd9519420ba7405e1307bff33214' 89 | expect(subject.plan_pending.price).to be 20 90 | end 91 | 92 | it 'is possible to reload the plan_pending object' do 93 | expect(faraday).to receive(:get).once.and_call_original 94 | 95 | expect(subject.plan_pending.name).to eq 'Pro Plan' 96 | end 97 | end 98 | 99 | context '#owner' do 100 | it 'returns the `owner` as actual object' do 101 | expect(subject.owner).not_to be_a Hash 102 | end 103 | 104 | it 'passes all the value to the `owner` object' do 105 | expect(faraday).to receive(:get).once.and_call_original 106 | 107 | expect(subject.owner.id).to eq '7c5dae5552338874e5053f2534d2767a' 108 | expect(subject.owner.email).to eq 'user@example.com' 109 | end 110 | 111 | it 'is possible to reload the `owner` object' do 112 | expect(faraday).to receive(:get).once.and_call_original 113 | 114 | expect(subject.owner.owner_type).to eq 'user' 115 | end 116 | end 117 | end 118 | 119 | describe '#update' do 120 | before do 121 | faraday_stubs.patch(url, 'paused' => true) do |_env| 122 | [200, { content_type: 'application/json' }, response_json] 123 | end 124 | end 125 | 126 | it 'returns the value that has been set' do 127 | subject.paused = true 128 | expect(subject.paused).to be true 129 | end 130 | 131 | it 'sends PATCH to the server' do 132 | expect(faraday).to receive(:patch).and_call_original 133 | 134 | subject.paused = true 135 | expect(subject.patch).to be subject 136 | # false, because the response is loaded from the server! 137 | # this is a good way to check if the @dirty hash is cleaned 138 | expect(subject.paused).to be false 139 | end 140 | 141 | it 'updates the value and sends PATCH to the server' do 142 | expect(faraday).to receive(:patch).and_call_original 143 | 144 | expect(subject.update(paused: true)).to be subject 145 | expect(subject.paused).to be false 146 | end 147 | end 148 | 149 | describe '#delete' do 150 | let(:response_json) { File.read('spec/cloudflair/fixtures/zone/delete.json') } 151 | 152 | before do 153 | faraday_stubs.delete(url) do |_env| 154 | [200, { content_type: 'application/json' }, response_json] 155 | end 156 | end 157 | 158 | it 'deletes the entity from the server' do 159 | expect(faraday).to receive(:delete).and_call_original 160 | 161 | expect(subject.delete).to be subject 162 | end 163 | 164 | it 'calls the server only once' do 165 | expect(faraday).to receive(:delete).once.and_call_original 166 | 167 | expect(subject.delete).to be subject 168 | expect(subject.delete).to be subject 169 | end 170 | 171 | it 'parses the response' do 172 | expect(subject.delete).to be subject 173 | expect(subject.id).to eq zone_identifier 174 | expect { subject.name }.to raise_error NoMethodError 175 | end 176 | end 177 | end 178 | -------------------------------------------------------------------------------- /spec/cloudflair/api_railguns_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair, 'railguns' do 6 | let(:railgun_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | 8 | describe '#railgun' do 9 | it 'returns a railgun object' do 10 | expect(subject.railgun(railgun_identifier)).not_to be_nil 11 | expect(subject.railgun(railgun_identifier)).to be_a Cloudflair::Railguns 12 | end 13 | 14 | it 'returns the correct railgun object' do 15 | expect(subject.railgun(railgun_identifier).railgun_id).to eq railgun_identifier 16 | end 17 | 18 | it 'returns a new railgun every time' do 19 | a = subject.railgun railgun_identifier 20 | b = subject.railgun railgun_identifier 21 | 22 | expect(a).not_to be_nil 23 | expect(b).not_to be_nil 24 | 25 | expect(a).to be_a Cloudflair::Railguns 26 | expect(b).to be_a Cloudflair::Railguns 27 | 28 | expect(a.railgun_id).to eq railgun_identifier 29 | expect(b.railgun_id).to eq railgun_identifier 30 | 31 | expect(a).not_to be b 32 | expect(b).not_to be a 33 | end 34 | end 35 | 36 | describe '#railguns' do 37 | let(:response_json) { File.read('spec/cloudflair/fixtures/railguns.json') } 38 | let(:expected_params) { {} } 39 | let(:url) { '/client/v4/railguns' } 40 | 41 | before do 42 | faraday_stubs.get(url) do |env| 43 | expect(env.url.query).to eq(url_query) 44 | 45 | [200, { content_type: 'application/json' }, response_json] 46 | end 47 | allow(Faraday).to receive(:new).and_return faraday 48 | end 49 | 50 | context 'no filters' do 51 | let(:url_query) { nil } 52 | 53 | it 'calls the remote side' do 54 | expect(faraday).to receive(:get).and_call_original 55 | 56 | expect(subject.railguns.length).to be 1 57 | end 58 | 59 | it 'returns an array of railguns' do 60 | railguns = subject.railguns 61 | expect(railguns).to be_a Array 62 | 63 | railguns.each do |railgun| 64 | expect(railgun).to be_a Cloudflair::Railguns 65 | end 66 | end 67 | 68 | it 'returned railguns are pre-populated' do 69 | expect(faraday).to receive(:get).once.and_call_original 70 | 71 | expect(subject.railguns[0].name).to eq('My Railgun') 72 | end 73 | end 74 | 75 | context 'filters' do 76 | let(:url_query) do 77 | 'direction=desc&page=1&per_page=20' 78 | end 79 | 80 | it 'calls the remote side with the query params' do 81 | expect(faraday).to receive(:get).and_call_original 82 | 83 | subject.railguns page: 1, 84 | per_page: 20, 85 | direction: 'desc' 86 | end 87 | end 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /spec/cloudflair/api_zones_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair, 'zones' do 6 | let(:zone_identifier) { '023e105f4ecef8ad9ca31a8372d0c353' } 7 | 8 | describe '#zone' do 9 | it 'returns a zone object' do 10 | expect(subject.zone(zone_identifier)).not_to be_nil 11 | expect(subject.zone(zone_identifier)).to be_a Cloudflair::Zone 12 | end 13 | 14 | it 'returns the correct zone object' do 15 | expect(subject.zone(zone_identifier).zone_id).to eq zone_identifier 16 | end 17 | 18 | it 'returns a new zone every time' do 19 | a = subject.zone zone_identifier 20 | b = subject.zone zone_identifier 21 | 22 | expect(a).not_to be_nil 23 | expect(b).not_to be_nil 24 | 25 | expect(a).to be_a Cloudflair::Zone 26 | expect(b).to be_a Cloudflair::Zone 27 | 28 | expect(a.zone_id).to eq zone_identifier 29 | expect(b.zone_id).to eq zone_identifier 30 | 31 | expect(a).not_to be b 32 | expect(b).not_to be a 33 | end 34 | end 35 | 36 | describe '#zones' do 37 | let(:response_json) { File.read('spec/cloudflair/fixtures/zones.json') } 38 | let(:expected_params) { {} } 39 | let(:url) { '/client/v4/zones' } 40 | 41 | before do 42 | faraday_stubs.get(url) do |env| 43 | expect(env.url.query).to eq(url_query) 44 | 45 | [200, { content_type: 'application/json' }, response_json] 46 | end 47 | allow(Faraday).to receive(:new).and_return faraday 48 | end 49 | 50 | context 'no filters' do 51 | let(:url_query) { nil } 52 | 53 | it 'calls the remote side' do 54 | expect(faraday).to receive(:get).and_call_original 55 | 56 | expect(subject.zones.length).to be 1 57 | end 58 | 59 | it 'returns an array of Zones' do 60 | zones = subject.zones 61 | expect(zones).to be_a Array 62 | 63 | zones.each do |zone| 64 | expect(zone).to be_a Cloudflair::Zone 65 | end 66 | end 67 | 68 | it 'returned Zones are pre-populated' do 69 | expect(faraday).to receive(:get).once.and_call_original 70 | 71 | expect(subject.zones[0].name).to eq('example.com') 72 | end 73 | 74 | context 'no results' do 75 | let(:response_json) { File.read('spec/cloudflair/fixtures/no_zones.json') } 76 | 77 | it 'returns an empty Array' do 78 | zones = subject.zones 79 | expect(zones).to be_a Array 80 | expect(zones.length).to be 0 81 | end 82 | end 83 | end 84 | 85 | context 'filters' do 86 | context 'name' do 87 | let(:url_query) { 'name=Hello' } 88 | 89 | it 'calls the remote side with the query params' do 90 | expect(faraday).to receive(:get).and_call_original 91 | 92 | subject.zones name: 'Hello' 93 | end 94 | end 95 | 96 | context 'all combined' do 97 | let(:url_query) do 98 | 'match=all&name=example.com&order=desc&page=1&per_page=20&status=active' 99 | end 100 | 101 | it 'calls the remote side with the query params' do 102 | expect(faraday).to receive(:get).and_call_original 103 | 104 | subject.zones name: 'example.com', 105 | status: 'active', 106 | page: 1, 107 | per_page: 20, 108 | order: 'desc', 109 | match: 'all' 110 | end 111 | end 112 | end 113 | end 114 | end 115 | -------------------------------------------------------------------------------- /spec/cloudflair/cloudflair_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair do 6 | it 'has a version number' do 7 | expect(File.read('VERSION')).not_to be nil 8 | end 9 | 10 | it 'is configurable' do 11 | described_class.configure do |config| 12 | config.cloudflare.auth.key = 'MY_AUTH_KEY' 13 | config.cloudflare.auth.email = 'MY_AUTH_EMAIL' 14 | config.cloudflare.auth.user_service_key = 'MY_AUTH_USER_SERVICE_KEY' 15 | config.cloudflare.api_base_url = 'https://cloudflair.mock.local' 16 | config.faraday.adapter = :net_http_persistent 17 | end 18 | 19 | expect(described_class.config.cloudflare.auth.key).to eq 'MY_AUTH_KEY' 20 | expect(described_class.config.cloudflare.auth.email).to eq 'MY_AUTH_EMAIL' 21 | expect(described_class.config.cloudflare.auth.user_service_key).to eq 'MY_AUTH_USER_SERVICE_KEY' 22 | expect(described_class.config.cloudflare.api_base_url).to eq 'https://cloudflair.mock.local' 23 | expect(described_class.config.faraday.adapter).to be :net_http_persistent 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/cloudflair/communication_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'json' 5 | 6 | describe Cloudflair::Communication do 7 | let(:faraday) { double('Faraday') } 8 | let(:url) { '/client/v4/tests/42' } 9 | let(:response) { double('response', body: response_body, status: 200) } 10 | 11 | let(:subject) { Victim.new } 12 | 13 | class Victim 14 | include Cloudflair::Communication 15 | end 16 | 17 | describe 'get connection' do 18 | it 'returns a valid connection' do 19 | expect(Cloudflair::Connection).to receive(:new).and_return faraday 20 | 21 | expect(subject.connection).to be faraday 22 | end 23 | 24 | it "does not cache it's connection" do 25 | expect(Cloudflair::Connection).to receive(:new).twice.and_return faraday 26 | 27 | expect(subject.connection).to be faraday 28 | expect(subject.connection).to be faraday 29 | end 30 | end 31 | 32 | describe 'valid response' do 33 | let(:result_json) do 34 | '{"name":"Beat","boolean":true,"number":1,"float_number":1.2,"date":"2014-05-28T18:46:18.764425Z"}' 35 | end 36 | let(:response_body) do 37 | JSON 38 | .parse( 39 | '{"success":true,"errors":[],"messages":[],"result":' + 40 | result_json + 41 | ',"result_info":{"page":1,"per_page":20,"count":1,"total_count":2000}}' 42 | ) 43 | end 44 | 45 | it 'parses the response' do 46 | expect(subject.response(response)).to eq(JSON.parse(result_json)) 47 | end 48 | end 49 | 50 | describe 'illegal response format' do 51 | let(:response_body) { JSON.parse '{"name":"This is not the expected JSON structure."}' } 52 | 53 | it 'raises the appropriate exception' do 54 | expect { subject.response(response) }.to raise_error Cloudflair::CloudflairError 55 | end 56 | end 57 | 58 | describe 'error response' do 59 | let(:response_body) do 60 | JSON.parse( 61 | '{"result":null,"success":false,"errors":[{"code":1003,"message":"Invalid or missing zone id."}],"messages":[]}' 62 | ) 63 | end 64 | 65 | it 'raises the appropriate exception' do 66 | expect { subject.response(response) } 67 | .to raise_error(Cloudflair::CloudflareError, '[ "Invalid or missing zone id." (Code: 1003) ]') 68 | end 69 | end 70 | 71 | describe 'http status checks' do 72 | context '304 Not Modified' do 73 | let(:response) { double('response', status: 304) } 74 | 75 | it 'returns and empty object' do 76 | expect(subject.response(response)).to be_nil 77 | end 78 | end 79 | 80 | context '400 Bad Request' do 81 | let(:response) { double('response', status: 400) } 82 | 83 | it 'returns and empty object' do 84 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 85 | end 86 | end 87 | 88 | context '401 Unauthorized' do 89 | let(:response) { double('response', status: 401) } 90 | 91 | it 'returns and empty object' do 92 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 93 | end 94 | end 95 | 96 | context '403 Forbidden' do 97 | let(:response) { double('response', status: 403) } 98 | 99 | it 'returns and empty object' do 100 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 101 | end 102 | end 103 | 104 | context '429 Too many requests' do 105 | let(:response) { double('response', status: 429) } 106 | 107 | it 'returns and empty object' do 108 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 109 | end 110 | end 111 | 112 | context '405 Method Not Allowed' do 113 | let(:response) { double('response', status: 405) } 114 | 115 | it 'returns and empty object' do 116 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 117 | end 118 | end 119 | 120 | context '415 Unsupported Media Type' do 121 | let(:response) { double('response', status: 415) } 122 | 123 | it 'returns and empty object' do 124 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 125 | end 126 | end 127 | 128 | context '499 Random' do 129 | let(:response) { double('response', status: 499) } 130 | 131 | it 'returns and empty object' do 132 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 133 | end 134 | end 135 | 136 | context '500 Internal Server Error' do 137 | let(:response) { double('response', status: 500) } 138 | 139 | it 'returns and empty object' do 140 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 141 | end 142 | end 143 | 144 | context '600 Undefined Error' do 145 | let(:response) { double('response', status: 600) } 146 | 147 | it 'returns and empty object' do 148 | expect { subject.response response }.to raise_error Cloudflair::CloudflairError 149 | end 150 | end 151 | end 152 | end 153 | -------------------------------------------------------------------------------- /spec/cloudflair/connection_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'uri' 5 | 6 | describe Cloudflair::Connection do 7 | describe 'email and key' do 8 | before do 9 | Cloudflair.configure do |config| 10 | config.cloudflare.auth.key = 'c2547eb745079dac9320b638f5e225cf483cc5cfdda41' 11 | config.cloudflare.auth.email = 'user@example.com' 12 | config.cloudflare.auth.user_service_key = nil 13 | config.cloudflare.api_base_url = 'https://cloudflair.mock.local' 14 | config.faraday.adapter = :net_http 15 | config.faraday.logger = nil 16 | end 17 | end 18 | 19 | it 'returns a Faraday::Connection' do 20 | expect(described_class.new).to be_a Faraday::Connection 21 | end 22 | 23 | it 'correctly sets the base url' do 24 | expect(described_class.new.url_prefix) 25 | .to eq(URI.parse('https://cloudflair.mock.local')) 26 | end 27 | 28 | it 'sets the correct auth headers' do 29 | actual_headers = described_class.new.headers 30 | expect(actual_headers['X-Auth-Key']).to eq 'c2547eb745079dac9320b638f5e225cf483cc5cfdda41' 31 | expect(actual_headers['X-Auth-Email']).to eq 'user@example.com' 32 | expect(actual_headers['X-Auth-User-Service-Key']).to be_nil 33 | end 34 | 35 | it 'sets the adapter' do 36 | expect(described_class.new.builder.handlers) 37 | .to include Faraday::Adapter::NetHttp 38 | end 39 | 40 | it 'adds the json middleware' do 41 | expect(described_class.new.builder.handlers) 42 | .to include FaradayMiddleware::ParseJson 43 | end 44 | end 45 | 46 | describe 'user service key' do 47 | before do 48 | Cloudflair.configure do |config| 49 | config.cloudflare.auth.key = nil 50 | config.cloudflare.auth.email = nil 51 | config.cloudflare.auth.user_service_key = 'v1.0-e24fd090c02efcfecb4de8f4ff246fd5c75b48946fdf0ce26c59f91d0d90797b-cfa33fe60e8e34073c149323454383fc9005d25c9b4c502c2f063457ef65322eade065975001a0b4b4c591c5e1bd36a6e8f7e2d4fa8a9ec01c64c041e99530c2-07b9efe0acd78c82c8d9c690aacb8656d81c369246d7f996a205fe3c18e9254a' 52 | config.cloudflare.api_base_url = 'https://cloudflair.mock.local' 53 | config.faraday.adapter = :net_http_persistent 54 | end 55 | end 56 | 57 | it 'sets the correct auth headers' do 58 | actual_headers = described_class.new.headers 59 | expect(actual_headers['X-Auth-Key']).to be_nil 60 | expect(actual_headers['X-Auth-Email']).to be_nil 61 | expect(actual_headers['Authorization']).to eq 'Bearer v1.0-e24fd090c02efcfecb4de8f4ff246fd5c75b48946fdf0ce26c59f91d0d90797b-cfa33fe60e8e34073c149323454383fc9005d25c9b4c502c2f063457ef65322eade065975001a0b4b4c591c5e1bd36a6e8f7e2d4fa8a9ec01c64c041e99530c2-07b9efe0acd78c82c8d9c690aacb8656d81c369246d7f996a205fe3c18e9254a' 62 | end 63 | end 64 | 65 | describe 'alternative adapter' do 66 | before do 67 | Cloudflair.configure do |config| 68 | config.cloudflare.auth.user_service_key = 'v1.0-e24fd090c02efcfecb4de8f4ff246fd5c75b48946fdf0ce26c59f91d0d90797b-cfa33fe60e8e34073c149323454383fc9005d25c9b4c502c2f063457ef65322eade065975001a0b4b4c591c5e1bd36a6e8f7e2d4fa8a9ec01c64c041e99530c2-07b9efe0acd78c82c8d9c690aacb8656d81c369246d7f996a205fe3c18e9254a' 69 | config.faraday.adapter = :net_http_persistent 70 | end 71 | end 72 | 73 | it 'sets the adapter' do 74 | expect(described_class.new.builder.handlers) 75 | .to include Faraday::Adapter::NetHttpPersistent 76 | end 77 | end 78 | 79 | describe 'alternative logger' do 80 | context 'faraday logger' do 81 | before do 82 | Cloudflair.configure do |config| 83 | config.cloudflare.auth.user_service_key = 'v1.0-e24fd090c02efcfecb4de8f4ff246fd5c75b48946fdf0ce26c59f91d0d90797b-cfa33fe60e8e34073c149323454383fc9005d25c9b4c502c2f063457ef65322eade065975001a0b4b4c591c5e1bd36a6e8f7e2d4fa8a9ec01c64c041e99530c2-07b9efe0acd78c82c8d9c690aacb8656d81c369246d7f996a205fe3c18e9254a' 84 | config.faraday.logger = :logger 85 | config.faraday.adapter = :net_http 86 | end 87 | end 88 | 89 | it 'sets the logger' do 90 | expect(described_class.new.builder.handlers) 91 | .to include Faraday::Response::Logger 92 | end 93 | end 94 | 95 | context 'detailed logger' do 96 | before do 97 | Cloudflair.configure do |config| 98 | config.cloudflare.auth.user_service_key = 'v1.0-e24fd090c02efcfecb4de8f4ff246fd5c75b48946fdf0ce26c59f91d0d90797b-cfa33fe60e8e34073c149323454383fc9005d25c9b4c502c2f063457ef65322eade065975001a0b4b4c591c5e1bd36a6e8f7e2d4fa8a9ec01c64c041e99530c2-07b9efe0acd78c82c8d9c690aacb8656d81c369246d7f996a205fe3c18e9254a' 99 | config.faraday.logger = :detailed_logger 100 | config.faraday.adapter = :net_http 101 | end 102 | end 103 | 104 | it 'sets the logger' do 105 | expect(described_class.new.builder.handlers) 106 | .to include Faraday::DetailedLogger::Middleware 107 | end 108 | end 109 | end 110 | end 111 | -------------------------------------------------------------------------------- /spec/cloudflair/entity_array_objectfields_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Entity do 6 | class TestEntity 7 | include Cloudflair::Entity 8 | 9 | attr_accessor :name 10 | 11 | patchable_fields :name 12 | deletable true 13 | path 'tests/:test_id' 14 | object_fields :an_object 15 | array_object_fields :an_object_array 16 | 17 | def initialize(name = 'Urs') 18 | @name = name 19 | end 20 | 21 | private 22 | 23 | def test_id 24 | 42 25 | end 26 | end 27 | class TestSubPoro 28 | attr_accessor :name 29 | 30 | def initialize(data) 31 | @name = data['name'] 32 | end 33 | end 34 | class TestEntity5 35 | include Cloudflair::Entity 36 | 37 | attr_accessor :test_id 38 | path 'tests/:test_id' 39 | array_object_fields an_object_array: TestSubPoro 40 | 41 | def initialize 42 | @test_id = 42 43 | end 44 | end 45 | class TestSubEntity 46 | include Cloudflair::Entity 47 | 48 | attr_accessor :my_id 49 | path 'tests/:my_id/sub' 50 | 51 | def initialize(my_id, data = nil) 52 | @my_id = my_id 53 | self.data = data 54 | end 55 | end 56 | class TestEntity6 57 | include Cloudflair::Entity 58 | 59 | attr_accessor :test_id 60 | path 'tests/:test_id' 61 | array_object_fields an_object_array: proc { |data| TestSubEntity.new(@test_id, data) } 62 | 63 | def initialize 64 | @test_id = 42 65 | end 66 | end 67 | 68 | let(:faraday_stubs) { Faraday::Adapter::Test::Stubs.new } 69 | let(:faraday) do 70 | Faraday.new(url: 'https://api.cloudflare.com/client/v4/', headers: Cloudflair::Connection.headers) do |faraday| 71 | faraday.response :json, content_type: /\bjson$/ 72 | faraday.adapter :test, faraday_stubs 73 | end 74 | end 75 | let(:response_json) do 76 | result_json = <<-json 77 | { 78 | "name": "Beat", 79 | "boolean": true, 80 | "number": 1, 81 | "float_number": 1.2, 82 | "date": "2014-05-28T18:46:18.764425Z", 83 | "an_object": { 84 | "key": "value", 85 | "second": 2 86 | }, 87 | "an_array": [], 88 | "an_object_array": [{ 89 | "name": "obj1" 90 | }, { 91 | "name": "obj2" 92 | }, { 93 | "name": "obj3" 94 | }] 95 | } 96 | json 97 | 98 | '{"success":true,"errors":[],"messages":[],"result":' + 99 | result_json + 100 | ',"result_info":{"page":1,"per_page":20,"count":1,"total_count":2000}}' 101 | end 102 | let(:url) { '/client/v4/tests/42' } 103 | let(:subject) { TestEntity.new } 104 | 105 | before do 106 | faraday_stubs.get(url) do |_env| 107 | [200, { content_type: 'application/json' }, response_json] 108 | end 109 | allow(Faraday).to receive(:new).and_return faraday 110 | end 111 | 112 | describe 'objectification of the content of array fields' do 113 | context 'anonymous classes' do 114 | it 'does not return `an_object_array` as Hashes' do 115 | expect(subject.an_object_array).to be_a Array 116 | subject.an_object_array.each do |obj| 117 | expect(obj).not_to be_a Hash 118 | end 119 | end 120 | 121 | it 'returns the correct values' do 122 | arr = subject.an_object_array 123 | 124 | expect(arr[0].name).to eq 'obj1' 125 | expect(arr[1].name).to eq 'obj2' 126 | expect(arr[2].name).to eq 'obj3' 127 | end 128 | 129 | it 'does not call the server for the sub-object' do 130 | expect(faraday).to receive(:get).once.and_call_original 131 | 132 | expect(subject._name).to eq 'Beat' 133 | expect(subject.an_object_array).not_to be_a Hash 134 | end 135 | 136 | it 'is a new object everytime' do 137 | a = subject.an_object_array 138 | b = subject.an_object_array 139 | 140 | expect(a).not_to be b 141 | expect(b).not_to be a 142 | end 143 | end 144 | 145 | context 'poro classes' do 146 | let(:subject) { TestEntity5.new } 147 | 148 | it 'does not return `an_object_array` as Hashes' do 149 | expect(subject.an_object_array).to be_a Array 150 | subject.an_object_array.each do |obj| 151 | expect(obj).to be_a TestSubPoro 152 | end 153 | end 154 | 155 | it 'returns the correct values' do 156 | arr = subject.an_object_array 157 | 158 | expect(arr[0].name).to eq 'obj1' 159 | expect(arr[1].name).to eq 'obj2' 160 | expect(arr[2].name).to eq 'obj3' 161 | end 162 | 163 | it 'does not call the server for the sub-object' do 164 | expect(faraday).to receive(:get).once.and_call_original 165 | 166 | expect(subject._name).to eq 'Beat' 167 | expect(subject.an_object_array).not_to be_a Hash 168 | end 169 | 170 | it 'is a new object everytime' do 171 | a = subject.an_object_array 172 | b = subject.an_object_array 173 | 174 | expect(a).not_to be b 175 | expect(b).not_to be a 176 | end 177 | end 178 | 179 | context 'entity classes' do 180 | let(:subject) { TestEntity6.new } 181 | 182 | it 'does not return `an_object_array` as Hashes' do 183 | expect(subject.an_object_array).to be_a Array 184 | subject.an_object_array.each do |obj| 185 | expect(obj).to be_a TestSubEntity 186 | end 187 | end 188 | 189 | it 'returns the correct values' do 190 | arr = subject.an_object_array 191 | 192 | expect(arr[0].name).to eq 'obj1' 193 | expect(arr[1].name).to eq 'obj2' 194 | expect(arr[2].name).to eq 'obj3' 195 | end 196 | 197 | it 'does not call the server for the sub-object' do 198 | expect(faraday).to receive(:get).once.and_call_original 199 | 200 | expect(subject._name).to eq 'Beat' 201 | expect(subject.an_object_array).not_to be_a Hash 202 | end 203 | 204 | it 'is a new object everytime' do 205 | a = subject.an_object_array 206 | b = subject.an_object_array 207 | 208 | expect(a).not_to be b 209 | expect(b).not_to be a 210 | end 211 | end 212 | end 213 | end 214 | -------------------------------------------------------------------------------- /spec/cloudflair/entity_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::Entity do 6 | class TestEntity 7 | include Cloudflair::Entity 8 | 9 | attr_accessor :name 10 | 11 | patchable_fields :name 12 | deletable true 13 | path 'tests/:test_id' 14 | object_fields :an_object 15 | array_object_fields :an_object_array 16 | 17 | def initialize(name = 'Urs') 18 | @name = name 19 | end 20 | 21 | private 22 | 23 | def test_id 24 | 42 25 | end 26 | end 27 | class TestEntity2 28 | include Cloudflair::Entity 29 | 30 | # no patchable_fields 31 | # not deletable 32 | 33 | path 'tests/42' 34 | end 35 | class TestEntity3 36 | include Cloudflair::Entity 37 | 38 | # Wrong URL (starts with '/') 39 | path '/tests/42' 40 | end 41 | class TestEntity4 42 | include Cloudflair::Entity 43 | 44 | # no path defined 45 | end 46 | 47 | let(:faraday_stubs) { Faraday::Adapter::Test::Stubs.new } 48 | let(:faraday) do 49 | Faraday.new(url: 'https://api.cloudflare.com/client/v4/', headers: Cloudflair::Connection.headers) do |faraday| 50 | faraday.response :json, content_type: /\bjson$/ 51 | faraday.adapter :test, faraday_stubs 52 | end 53 | end 54 | let(:raw_data) do 55 | { 56 | 'name' => 'Beat', 57 | 'boolean' => true, 58 | 'number' => 1, 59 | 'float_number' => 1.2, 60 | 'date' => '2014-05-28T18:46:18.764425Z', 61 | 'an_object' => { 62 | 'key' => 'value', 63 | 'second' => 2 64 | }, 65 | 'an_array' => [], 66 | 'an_object_array' => [ 67 | { 'name' => 'obj1' }, 68 | { 'name' => 'obj2' }, 69 | { 'name' => 'obj3' } 70 | ] 71 | } 72 | end 73 | let(:response_json) do 74 | '{"success":true,"errors":[],"messages":[],"result":' + 75 | JSON.generate(raw_data) + 76 | ',"result_info":{"page":1,"per_page":20,"count":1,"total_count":2000}}' 77 | end 78 | let(:url) { '/client/v4/tests/42' } 79 | let(:subject) { TestEntity.new } 80 | 81 | before do 82 | faraday_stubs.get(url) do |_env| 83 | [200, { content_type: 'application/json' }, response_json] 84 | end 85 | allow(Faraday).to receive(:new).and_return faraday 86 | end 87 | 88 | it 'gets the name from the TestEntity' do 89 | expect(subject.name).to eq 'Urs' 90 | end 91 | 92 | describe 'fetch values' do 93 | it 'returns the correct name' do 94 | expect(subject._name).to eq 'Beat' 95 | end 96 | 97 | it 'caches the data' do 98 | expect(faraday).to receive(:get).once.and_call_original 99 | 100 | expect(subject._name).to eq 'Beat' 101 | expect(subject._name).to eq 'Beat' 102 | end 103 | 104 | it 'fetches the data when asked to' do 105 | expect(faraday).to receive(:get).twice.and_call_original 106 | subject.reload 107 | subject.reload 108 | end 109 | 110 | it 'returns itself when reloading' do 111 | expect(subject.reload).to be subject 112 | end 113 | 114 | it 'raises a NoMethodError when the field is not in the response' do 115 | expect { subject.nope }.to raise_error NoMethodError 116 | end 117 | 118 | it 'returns a number' do 119 | expect(subject.number).to be 1 120 | end 121 | 122 | it 'returns a floating-point number' do 123 | expect(subject.float_number).to be 1.2 124 | end 125 | 126 | it 'returns an Array' do 127 | expect(subject.an_array).to be_a Array 128 | expect(subject.an_array.length).to be 0 129 | end 130 | 131 | it 'returns the raw data' do 132 | expect(subject._raw_data!).to eq raw_data 133 | end 134 | end 135 | 136 | describe 'send values' do 137 | before do 138 | faraday_stubs.patch(url, 'name' => 'Fritz') do |_env| 139 | [200, { content_type: 'application/json' }, response_json] 140 | end 141 | end 142 | 143 | it 'raises a NoMethodError when the field is not modifiable' do 144 | expect { subject.nope = false }.to raise_error NoMethodError 145 | end 146 | 147 | it 'returns the value that has been set' do 148 | subject.name = 'Fritz' 149 | subject._name = 'Alfred' 150 | expect(subject.name).to eq 'Fritz' 151 | expect(subject._name).to eq 'Alfred' 152 | end 153 | 154 | it 'sends PATCH to the server' do 155 | expect(faraday).to receive(:patch).and_call_original 156 | 157 | subject._name = 'Fritz' 158 | expect(subject.patch).to be subject 159 | expect(subject.name).to eq 'Urs' 160 | 161 | # this value is read from the response, which is 'Beat', and not 'Fritz' 162 | # this also checks implicitly that the @dirty cache has been emptied 163 | expect(subject._name).to eq 'Beat' 164 | end 165 | 166 | it 'updates the value and sends PATCH to the server' do 167 | expect(faraday).to receive(:patch).and_call_original 168 | 169 | expect(subject.update(name: 'Fritz')).to be subject 170 | expect(subject.name).to eq 'Urs' 171 | 172 | # this value is read from the response, which is 'Beat', and not 'Fritz' 173 | # this also checks implicitly that the @dirty cache has been emptied 174 | expect(subject._name).to eq 'Beat' 175 | end 176 | 177 | it 'updates only allowed values and sends PATCH to the server' do 178 | expect(faraday).to receive(:patch).and_call_original 179 | 180 | expect(subject.update(name: 'Fritz', illegal: 'It Is')).to be subject 181 | end 182 | 183 | it 'does not send PATCH to the server when nothing changed' do 184 | expect(faraday).not_to receive(:patch) 185 | 186 | expect(subject.patch).to be subject 187 | end 188 | 189 | it 'does not send PATCH to the server when nothing valid changed' do 190 | expect(faraday).not_to receive(:patch) 191 | 192 | expect(subject.update(illegal: 'It Is')).to be subject 193 | end 194 | end 195 | 196 | describe 'api class has no patchable_fields' do 197 | let(:subject) { TestEntity2.new } 198 | 199 | it 'still runs a fetch' do 200 | expect(faraday).to receive(:get).once.and_call_original 201 | 202 | expect(subject.name).to eq 'Beat' 203 | end 204 | 205 | it 'does not send PATCH' do 206 | expect(faraday).not_to receive(:patch) 207 | 208 | expect(subject.update(name: 'Fritz')).to be subject 209 | end 210 | 211 | it 'does not allow setting any value' do 212 | expect { subject.name = 'Mars' }.to raise_error NoMethodError 213 | end 214 | end 215 | 216 | describe 'delete entities' do 217 | let(:response_json) do 218 | '{"success":true,"errors":[],"messages":[],"result":{"id":42}}' 219 | end 220 | 221 | before do 222 | faraday_stubs.delete(url) do |_env| 223 | [200, { content_type: 'application/json' }, response_json] 224 | end 225 | end 226 | 227 | it 'deletes the entity from the server' do 228 | expect(faraday).to receive(:delete).and_call_original 229 | 230 | expect(subject.delete).to be subject 231 | end 232 | 233 | it 'calls the server only once' do 234 | expect(faraday).to receive(:delete).once.and_call_original 235 | 236 | expect(subject.delete).to be subject 237 | expect(subject.delete).to be subject 238 | end 239 | 240 | it 'parses the response' do 241 | expect(subject.delete).to be subject 242 | expect(subject.id).to be 42 243 | expect { subject._name }.to raise_error NoMethodError 244 | end 245 | 246 | context 'non-deletable entity' do 247 | let(:subject) { TestEntity2.new } 248 | 249 | it 'raises an error' do 250 | expect { subject.delete }.to raise_error Cloudflair::CloudflairError 251 | end 252 | end 253 | end 254 | 255 | describe 'a wrong path is given' do 256 | let(:subject) { TestEntity3.new } 257 | 258 | it 'raises an exception' do 259 | expect { subject.name }.to raise_error Faraday::Adapter::Test::Stubs::NotFound 260 | end 261 | end 262 | 263 | describe 'no path given' do 264 | let(:subject) { TestEntity4.new } 265 | 266 | it 'raises an exception' do 267 | expect { subject.reload }.to raise_error ArgumentError 268 | end 269 | end 270 | 271 | describe 'objectification of fields' do 272 | it 'does not return `an_object` as Hash' do 273 | expect(subject.an_object).not_to be_a Hash 274 | end 275 | 276 | it 'returns the correct values' do 277 | expect(subject.an_object).not_to be_a Hash 278 | expect(subject.an_object.key).to eq 'value' 279 | expect(subject.an_object.second).to be 2 280 | end 281 | 282 | it 'does not call the server for the sub-object' do 283 | expect(faraday).to receive(:get).once.and_call_original 284 | 285 | expect(subject._name).to eq 'Beat' 286 | expect(subject.an_object).not_to be_a Hash 287 | end 288 | 289 | it 'is a new object everytime' do 290 | a = subject.an_object 291 | b = subject.an_object 292 | 293 | expect(a).not_to be b 294 | expect(b).not_to be a 295 | end 296 | end 297 | end 298 | -------------------------------------------------------------------------------- /spec/cloudflair/error/cloudflare_error_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Cloudflair::CloudflareError do 6 | let(:cloudflare_errors) do 7 | [ 8 | { 'code' => 1003, 'message' => 'Invalid or missing zone id.' } 9 | ] 10 | end 11 | let(:subject) { described_class.new cloudflare_errors } 12 | 13 | it 'serializes the given errors' do 14 | expect(subject.to_s).to eq '[ "Invalid or missing zone id." (Code: 1003) ]' 15 | end 16 | 17 | context 'multiple errors' do 18 | let(:cloudflare_errors) do 19 | [ 20 | { 'code' => 1003, 'message' => 'Invalid or missing zone id.' }, 21 | { 'code' => 1003, 'message' => 'Invalid or missing zone id.' } 22 | ] 23 | end 24 | 25 | it 'serializes the given errors' do 26 | expect(subject.to_s) 27 | .to eq '[ "Invalid or missing zone id." (Code: 1003), "Invalid or missing zone id." (Code: 1003) ]' 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/no_zones.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [], 6 | "result_info": { 7 | "page": 1, 8 | "per_page": 20, 9 | "count": 0, 10 | "total_count": 0 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/railgun/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "e928d310693a83094309acf9ead50448" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/railgun/railgun.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "e928d310693a83094309acf9ead50448", 7 | "name": "My Railgun", 8 | "status": "active", 9 | "enabled": true, 10 | "zones_connected": 2, 11 | "build": "b1234", 12 | "version": "2.1", 13 | "revision": "123", 14 | "activation_key": "e4edc00281cb56ebac22c81be9bac8f3", 15 | "activated_on": "2014-01-02T02:20:00Z", 16 | "created_on": "2014-01-01T05:20:00Z", 17 | "modified_on": "2014-01-01T05:20:00Z" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/railgun/railgun_zones.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "id": "023e105f4ecef8ad9ca31a8372d0c353", 8 | "name": "example.com", 9 | "development_mode": 7200, 10 | "original_name_servers": [ 11 | "ns1.originaldnshost.com", 12 | "ns2.originaldnshost.com" 13 | ], 14 | "original_registrar": "GoDaddy", 15 | "original_dnshost": "NameCheap", 16 | "created_on": "2014-01-01T05:20:00.12345Z", 17 | "modified_on": "2014-01-01T05:20:00.12345Z" 18 | } 19 | ], 20 | "result_info": { 21 | "page": 1, 22 | "per_page": 20, 23 | "count": 1, 24 | "total_count": 2000 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/railguns.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "id": "e928d310693a83094309acf9ead50448", 8 | "name": "My Railgun", 9 | "status": "active", 10 | "enabled": true, 11 | "zones_connected": 2, 12 | "build": "b1234", 13 | "version": "2.1", 14 | "revision": "123", 15 | "activation_key": "e4edc00281cb56ebac22c81be9bac8f3", 16 | "activated_on": "2014-01-02T02:20:00Z", 17 | "created_on": "2014-01-01T05:20:00Z", 18 | "modified_on": "2014-01-01T05:20:00Z" 19 | } 20 | ], 21 | "result_info": { 22 | "page": 1, 23 | "per_page": 20, 24 | "count": 1, 25 | "total_count": 2000 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/analytics_colos.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "colo_id": "SFO", 8 | "timeseries": [ 9 | { 10 | "since": "2015-01-01T12:23:00Z", 11 | "until": "2015-01-02T12:23:00Z", 12 | "requests": { 13 | "all": 1234085328, 14 | "cached": 1234085328, 15 | "uncached": 13876154, 16 | "content_type": { 17 | "css": 15343, 18 | "html": 1234213, 19 | "javascript": 318236, 20 | "gif": 23178, 21 | "jpeg": 1982048 22 | }, 23 | "country": { 24 | "US": 4181364, 25 | "AG": 37298, 26 | "GI": 293846 27 | }, 28 | "ssl": { 29 | "encrypted": 12978361, 30 | "unencrypted": 781263 31 | }, 32 | "http_status": { 33 | "200": 13496983, 34 | "301": 283, 35 | "400": 187936, 36 | "402": 1828, 37 | "404": 1293 38 | } 39 | }, 40 | "bandwidth": { 41 | "all": 213867451, 42 | "cached": 113205063, 43 | "uncached": 113205063, 44 | "content_type": { 45 | "css": 237421, 46 | "html": 1231290, 47 | "javascript": 123245, 48 | "gif": 1234242, 49 | "jpeg": 784278 50 | }, 51 | "country": { 52 | "US": 123145433, 53 | "AG": 2342483, 54 | "GI": 984753 55 | }, 56 | "ssl": { 57 | "encrypted": 37592942, 58 | "unencrypted": 237654192 59 | } 60 | }, 61 | "threats": { 62 | "all": 23423873, 63 | "country": { 64 | "US": 123, 65 | "CN": 523423, 66 | "AU": 91 67 | }, 68 | "type": { 69 | "user.ban.ip": 123, 70 | "hot.ban.unknown": 5324, 71 | "macro.chl.captchaErr": 1341, 72 | "macro.chl.jschlErr": 5323 73 | } 74 | }, 75 | "pageviews": { 76 | "all": 5724723, 77 | "search_engines": { 78 | "googlebot": 35272, 79 | "pingdom": 13435, 80 | "bingbot": 5372, 81 | "baidubot": 1345 82 | } 83 | }, 84 | "uniques": { 85 | "all": 12343 86 | } 87 | } 88 | ] 89 | } 90 | ], 91 | "query": { 92 | "since": "2015-01-01T12:23:00Z", 93 | "until": "2015-01-02T12:23:00Z", 94 | "time_delta": 60 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/analytics_dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "totals": { 7 | "since": "2015-01-01T12:23:00Z", 8 | "until": "2015-01-02T12:23:00Z", 9 | "requests": { 10 | "all": 1234085328, 11 | "cached": 1234085328, 12 | "uncached": 13876154, 13 | "content_type": { 14 | "css": 15343, 15 | "html": 1234213, 16 | "javascript": 318236, 17 | "gif": 23178, 18 | "jpeg": 1982048 19 | }, 20 | "country": { 21 | "US": 4181364, 22 | "AG": 37298, 23 | "GI": 293846 24 | }, 25 | "ssl": { 26 | "encrypted": 12978361, 27 | "unencrypted": 781263 28 | }, 29 | "http_status": { 30 | "200": 13496983, 31 | "301": 283, 32 | "400": 187936, 33 | "402": 1828, 34 | "404": 1293 35 | } 36 | }, 37 | "bandwidth": { 38 | "all": 213867451, 39 | "cached": 113205063, 40 | "uncached": 113205063, 41 | "content_type": { 42 | "css": 237421, 43 | "html": 1231290, 44 | "javascript": 123245, 45 | "gif": 1234242, 46 | "jpeg": 784278 47 | }, 48 | "country": { 49 | "US": 123145433, 50 | "AG": 2342483, 51 | "GI": 984753 52 | }, 53 | "ssl": { 54 | "encrypted": 37592942, 55 | "unencrypted": 237654192 56 | } 57 | }, 58 | "threats": { 59 | "all": 23423873, 60 | "country": { 61 | "US": 123, 62 | "CN": 523423, 63 | "AU": 91 64 | }, 65 | "type": { 66 | "user.ban.ip": 123, 67 | "hot.ban.unknown": 5324, 68 | "macro.chl.captchaErr": 1341, 69 | "macro.chl.jschlErr": 5323 70 | } 71 | }, 72 | "pageviews": { 73 | "all": 5724723, 74 | "search_engines": { 75 | "googlebot": 35272, 76 | "pingdom": 13435, 77 | "bingbot": 5372, 78 | "baidubot": 1345 79 | } 80 | }, 81 | "uniques": { 82 | "all": 12343 83 | } 84 | }, 85 | "timeseries": [ 86 | { 87 | "since": "2015-01-01T12:23:00Z", 88 | "until": "2015-01-02T12:23:00Z", 89 | "requests": { 90 | "all": 1234085328, 91 | "cached": 1234085328, 92 | "uncached": 13876154, 93 | "content_type": { 94 | "css": 15343, 95 | "html": 1234213, 96 | "javascript": 318236, 97 | "gif": 23178, 98 | "jpeg": 1982048 99 | }, 100 | "country": { 101 | "US": 4181364, 102 | "AG": 37298, 103 | "GI": 293846 104 | }, 105 | "ssl": { 106 | "encrypted": 12978361, 107 | "unencrypted": 781263 108 | }, 109 | "http_status": { 110 | "200": 13496983, 111 | "301": 283, 112 | "400": 187936, 113 | "402": 1828, 114 | "404": 1293 115 | } 116 | }, 117 | "bandwidth": { 118 | "all": 213867451, 119 | "cached": 113205063, 120 | "uncached": 113205063, 121 | "content_type": { 122 | "css": 237421, 123 | "html": 1231290, 124 | "javascript": 123245, 125 | "gif": 1234242, 126 | "jpeg": 784278 127 | }, 128 | "country": { 129 | "US": 123145433, 130 | "AG": 2342483, 131 | "GI": 984753 132 | }, 133 | "ssl": { 134 | "encrypted": 37592942, 135 | "unencrypted": 237654192 136 | } 137 | }, 138 | "threats": { 139 | "all": 23423873, 140 | "country": { 141 | "US": 123, 142 | "CN": 523423, 143 | "AU": 91 144 | }, 145 | "type": { 146 | "user.ban.ip": 123, 147 | "hot.ban.unknown": 5324, 148 | "macro.chl.captchaErr": 1341, 149 | "macro.chl.jschlErr": 5323 150 | } 151 | }, 152 | "pageviews": { 153 | "all": 5724723, 154 | "search_engines": { 155 | "googlebot": 35272, 156 | "pingdom": 13435, 157 | "bingbot": 5372, 158 | "baidubot": 1345 159 | } 160 | }, 161 | "uniques": { 162 | "all": 12343 163 | } 164 | } 165 | ] 166 | }, 167 | "query": { 168 | "since": "2015-01-01T12:23:00Z", 169 | "until": "2015-01-02T12:23:00Z", 170 | "time_delta": 60 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/available_rate_plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "free", 7 | "name": "Free Plan", 8 | "currency": "USD", 9 | "duration": 1, 10 | "frequency": "monthly", 11 | "components": [ 12 | { 13 | "name": "page_rules", 14 | "default": 5, 15 | "unit_price": 1 16 | } 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/custom_hostname.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "0d89c70d-ad9f-4843-b99f-6cc0252067e9", 7 | "hostname": "app.example.com", 8 | "ssl": { 9 | "status": "pending_validation", 10 | "method": "http", 11 | "type": "dv", 12 | "cname_target": "dcv.digicert.com", 13 | "cname": "810b7d5f01154524b961ba0cd578acc2.app.example.com" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/custom_hostname_deleted.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "id": "8a5577f0-ed62-4716-8c1f-1ae34a7f7cdb", 4 | "ssl": null, 5 | "created_at": "2019-05-03T16:51:01.146758Z" 6 | }, 7 | "success": true, 8 | "errors": [], 9 | "messages": [] 10 | } 11 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/custom_hostnames.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "id": "0d89c70d-ad9f-4843-b99f-6cc0252067e9", 8 | "hostname": "app.example.com", 9 | "ssl": { 10 | "status": "pending_validation", 11 | "method": "http", 12 | "type": "dv", 13 | "cname_target": "dcv.digicert.com", 14 | "cname": "810b7d5f01154524b961ba0cd578acc2.app.example.com" 15 | } 16 | } 17 | ], 18 | "result_info": { 19 | "page": 1, 20 | "per_page": 20, 21 | "count": 1, 22 | "total_count": 2000 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "023e105f4ecef8ad9ca31a8372d0c353" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/details.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "023e105f4ecef8ad9ca31a8372d0c353", 7 | "name": "example.com", 8 | "development_mode": 7200, 9 | "original_name_servers": [ 10 | "ns1.originaldnshost.com", 11 | "ns2.originaldnshost.com" 12 | ], 13 | "original_registrar": "GoDaddy", 14 | "original_dnshost": "NameCheap", 15 | "created_on": "2014-01-01T05:20:00.12345Z", 16 | "modified_on": "2014-01-01T05:20:00.12345Z", 17 | "name_servers": [ 18 | "tony.ns.cloudflare.com", 19 | "woz.ns.cloudflare.com" 20 | ], 21 | "owner": { 22 | "id": "7c5dae5552338874e5053f2534d2767a", 23 | "email": "user@example.com", 24 | "owner_type": "user" 25 | }, 26 | "permissions": [ 27 | "#zone:read", 28 | "#zone:edit" 29 | ], 30 | "plan": { 31 | "id": "e592fd9519420ba7405e1307bff33214", 32 | "name": "Pro Plan", 33 | "price": 20, 34 | "currency": "USD", 35 | "frequency": "monthly", 36 | "legacy_id": "pro", 37 | "is_subscribed": true, 38 | "can_subscribe": true 39 | }, 40 | "plan_pending": { 41 | "id": "e592fd9519420ba7405e1307bff33214", 42 | "name": "Pro Plan", 43 | "price": 20, 44 | "currency": "USD", 45 | "frequency": "monthly", 46 | "legacy_id": "pro", 47 | "is_subscribed": true, 48 | "can_subscribe": true 49 | }, 50 | "status": "active", 51 | "paused": false, 52 | "type": "full", 53 | "checked_on": "2014-01-01T05:20:00.12345Z" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/dns_record.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "372e67954025e0ba6aaa6d586b9e0b59", 7 | "type": "A", 8 | "name": "example.com", 9 | "content": "1.2.3.4", 10 | "proxiable": true, 11 | "proxied": false, 12 | "ttl": 120, 13 | "locked": false, 14 | "zone_id": "023e105f4ecef8ad9ca31a8372d0c353", 15 | "zone_name": "example.com", 16 | "created_on": "2014-01-01T05:20:00.12345Z", 17 | "modified_on": "2014-01-01T05:20:00.12345Z", 18 | "data": {} 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/dns_record_deleted.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "372e67954025e0ba6aaa6d586b9e0b59" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/dns_records.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "id": "372e67954025e0ba6aaa6d586b9e0b59", 8 | "type": "A", 9 | "name": "example.com", 10 | "content": "1.2.3.4", 11 | "proxiable": true, 12 | "proxied": false, 13 | "ttl": 120, 14 | "locked": false, 15 | "zone_id": "023e105f4ecef8ad9ca31a8372d0c353", 16 | "zone_name": "example.com", 17 | "created_on": "2014-01-01T05:20:00.12345Z", 18 | "modified_on": "2014-01-01T05:20:00.12345Z", 19 | "data": {} 20 | } 21 | ], 22 | "result_info": { 23 | "page": 1, 24 | "per_page": 20, 25 | "count": 1, 26 | "total_count": 2000 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/plan.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "e592fd9519420ba7405e1307bff33214", 7 | "name": "Pro Plan", 8 | "price": 20, 9 | "currency": "USD", 10 | "frequency": "monthly", 11 | "legacy_id": "pro", 12 | "is_subscribed": true, 13 | "can_subscribe": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "id": "e592fd9519420ba7405e1307bff33214", 8 | "name": "Pro Plan", 9 | "price": 20, 10 | "currency": "USD", 11 | "frequency": "monthly", 12 | "legacy_id": "pro", 13 | "is_subscribed": true, 14 | "can_subscribe": true 15 | } 16 | ], 17 | "result_info": { 18 | "page": 1, 19 | "per_page": 20, 20 | "count": 1, 21 | "total_count": 2000 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/purge_cache.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "023e105f4ecef8ad9ca31a8372d0c353" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/railgun.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "e928d310693a83094309acf9ead50448", 7 | "name": "My Railgun", 8 | "enabled": true, 9 | "connected": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/railgun_diagnose.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "method": "GET", 7 | "host_name": "www.example.com", 8 | "http_status": 200, 9 | "railgun": "on", 10 | "url": "https://www.cloudflare.com", 11 | "response_status": "200 OK", 12 | "protocol": "HTTP/1.1", 13 | "elapsed_time": "0.239013s", 14 | "body_size": "63910 bytes", 15 | "body_hash": "be27f2429421e12f200cab1da43ba301bdc70e1d", 16 | "missing_headers": "No Content-Length or Transfer-Encoding", 17 | "connection_close": false, 18 | "cloudflare": "on", 19 | "cf-ray": "1ddd7570575207d9-LAX", 20 | "cf-wan-error": null, 21 | "cf-cache-status": null 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/railguns.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "id": "e928d310693a83094309acf9ead50448", 8 | "name": "My Railgun", 9 | "enabled": true, 10 | "connected": true 11 | } 12 | ], 13 | "result_info": { 14 | "page": 1, 15 | "per_page": 20, 16 | "count": 1, 17 | "total_count": 2000 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/advanced_ddos.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "advanced_ddos", 7 | "value": "on", 8 | "editable": false, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/always_online.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "always_online", 7 | "value": "on", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/browser_cache_ttl.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "browser_cache_ttl", 7 | "value": 14400, 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/browser_check.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "browser_check", 7 | "value": "on", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/cache_level.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "cache_level", 7 | "value": "aggressive", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/challenge_ttl.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "challenge_ttl", 7 | "value": 1800, 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/development_mode.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "development_mode", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z", 10 | "time_remaining": 3600 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/development_mode_without_time_remaining.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "development_mode", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/email_obfuscation.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "email_obfuscation", 7 | "value": "on", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/hotlink_protection.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "hotlink_protection", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/ip_geolocation.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "ip_geolocation", 7 | "value": "on", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/ipv6.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "ipv6", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/minify.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "minify", 7 | "value": { 8 | "css": "off", 9 | "html": "off", 10 | "js": "off" 11 | }, 12 | "editable": true, 13 | "modified_on": "2014-01-01T05:20:00.12345Z" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/mirage.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "mirage", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/mobile_redirect.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "mobile_redirect", 7 | "value": { 8 | "status": "off", 9 | "mobile_subdomain": "m", 10 | "strip_uri": false 11 | }, 12 | "editable": true, 13 | "modified_on": "2014-01-01T05:20:00.12345Z" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/origin_error_page_pass_thru.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": "off" 6 | } 7 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/polish.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "polish", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/prefetch_preload.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": "off" 6 | } 7 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/response_buffering.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": "off" 6 | } 7 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/rocket_loader.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "rocket_loader", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/security_header.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "security_header", 7 | "value": { 8 | "strict_transport_security": { 9 | "enabled": true, 10 | "max_age": 86400, 11 | "include_subdomains": true, 12 | "nosniff": true 13 | } 14 | }, 15 | "editable": true, 16 | "modified_on": "2014-01-01T05:20:00.12345Z" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/security_level.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "security_level", 7 | "value": "medium", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/server_side_exclude.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "server_side_exclude", 7 | "value": "on", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/sort_query_string_for_cache.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": "off" 6 | } 7 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/ssl.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "ssl", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/tls_1_2_only.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": "off" 6 | } 7 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/tls_1_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": "off" 6 | } 7 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/tls_client_auth.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "tls_client_auth", 7 | "value": "on", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/true_client_ip_header.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": "off" 6 | } 7 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/waf.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "waf", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zone/settings/websockets.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": { 6 | "id": "websockets", 7 | "value": "off", 8 | "editable": true, 9 | "modified_on": "2014-01-01T05:20:00.12345Z" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/cloudflair/fixtures/zones.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "errors": [], 4 | "messages": [], 5 | "result": [ 6 | { 7 | "id": "023e105f4ecef8ad9ca31a8372d0c353", 8 | "name": "example.com", 9 | "development_mode": 7200, 10 | "original_name_servers": [ 11 | "ns1.originaldnshost.com", 12 | "ns2.originaldnshost.com" 13 | ], 14 | "original_registrar": "GoDaddy", 15 | "original_dnshost": "NameCheap", 16 | "created_on": "2014-01-01T05:20:00.12345Z", 17 | "modified_on": "2014-01-01T05:20:00.12345Z", 18 | "name_servers": [ 19 | "tony.ns.cloudflare.com", 20 | "woz.ns.cloudflare.com" 21 | ], 22 | "owner": { 23 | "id": "7c5dae5552338874e5053f2534d2767a", 24 | "email": "user@example.com", 25 | "owner_type": "user" 26 | }, 27 | "permissions": [ 28 | "#zone:read", 29 | "#zone:edit" 30 | ], 31 | "plan": { 32 | "id": "e592fd9519420ba7405e1307bff33214", 33 | "name": "Pro Plan", 34 | "price": 20, 35 | "currency": "USD", 36 | "frequency": "monthly", 37 | "legacy_id": "pro", 38 | "is_subscribed": true, 39 | "can_subscribe": true 40 | }, 41 | "plan_pending": { 42 | "id": "e592fd9519420ba7405e1307bff33214", 43 | "name": "Pro Plan", 44 | "price": 20, 45 | "currency": "USD", 46 | "frequency": "monthly", 47 | "legacy_id": "pro", 48 | "is_subscribed": true, 49 | "can_subscribe": true 50 | }, 51 | "status": "active", 52 | "paused": false, 53 | "type": "full", 54 | "checked_on": "2014-01-01T05:20:00.12345Z" 55 | } 56 | ], 57 | "result_info": { 58 | "page": 1, 59 | "per_page": 20, 60 | "count": 1, 61 | "total_count": 2000 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /spec/shared_context.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | require 'cloudflair' 6 | require 'faraday' 7 | require 'faraday_middleware' 8 | require 'faraday/detailed_logger' 9 | 10 | RSpec.shared_context 'connection setup' do 11 | let(:cloudflare_api_base_url) { 'https://api.cloudflare.com/client/v4/' } 12 | 13 | let(:cloudflare_auth) do 14 | { 15 | key: 'test_api_key', 16 | email: 'test_account_email', 17 | user_service_key: nil 18 | } 19 | end 20 | 21 | let(:faraday) do 22 | Faraday.new( 23 | url: Cloudflair.config.cloudflare.api_base_url, 24 | headers: Cloudflair::Connection.headers 25 | ) do |faraday| 26 | faraday.response :json, content_type: /\bjson$/ 27 | faraday.response faraday_logger if faraday_logger 28 | faraday.adapter :test, faraday_stubs 29 | end 30 | end 31 | 32 | let(:faraday_logger) { :detailed_logger } 33 | let(:faraday_stubs) { Faraday::Adapter::Test::Stubs.new } 34 | 35 | before do 36 | Cloudflair.configure do |config| 37 | config.cloudflare.auth.key = cloudflare_auth[:key] 38 | config.cloudflare.auth.email = cloudflare_auth[:email] 39 | config.cloudflare.auth.user_service_key = cloudflare_auth[:user_service_key] 40 | config.cloudflare.api_base_url = cloudflare_api_base_url 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | $LOAD_PATH.unshift File.expand_path('../lib', __dir__) 4 | 5 | require 'shared_context' 6 | 7 | RSpec.configure do |config| 8 | config.run_all_when_everything_filtered = true 9 | config.filter_run :focus 10 | config.order = 'random' 11 | config.include_context 'connection setup' 12 | end 13 | 14 | require 'cloudflair' 15 | require 'cloudflair/entity' 16 | require 'cloudflair/connection' 17 | require 'cloudflair/communication' 18 | require 'cloudflair/error/cloudflare_error' 19 | require 'cloudflair/error/cloudflair_error' 20 | require 'cloudflair' 21 | require 'cloudflair/api' 22 | require 'cloudflair/api/railguns' 23 | require 'cloudflair/api/zone' 24 | require 'cloudflair/api/zone/analytics' 25 | require 'cloudflair/api/zone/available_plan' 26 | require 'cloudflair/api/zone/available_rate_plan' 27 | require 'cloudflair/api/zone/custom_hostname' 28 | require 'cloudflair/api/zone/dns_record' 29 | require 'cloudflair/api/zone/purge_cache' 30 | require 'cloudflair/api/zone/railgun' 31 | require 'cloudflair/api/zone/settings' 32 | require 'cloudflair/api/zone/settings/advanced_ddos' 33 | require 'cloudflair/api/zone/settings/always_online' 34 | require 'cloudflair/api/zone/settings/browser_cache_ttl' 35 | require 'cloudflair/api/zone/settings/cache_level' 36 | require 'cloudflair/api/zone/settings/challenge_ttl' 37 | require 'cloudflair/api/zone/settings/development_mode' 38 | require 'cloudflair/api/zone/settings/email_obfuscation' 39 | require 'cloudflair/api/zone/settings/hotlink_protection' 40 | require 'cloudflair/api/zone/settings/ip_geolocation' 41 | require 'cloudflair/api/zone/settings/ipv6' 42 | require 'cloudflair/api/zone/settings/minify' 43 | require 'cloudflair/api/zone/settings/mirage' 44 | require 'cloudflair/api/zone/settings/mobile_redirect' 45 | require 'cloudflair/api/zone/settings/origin_error_page_pass_thru' 46 | require 'cloudflair/api/zone/settings/polish' 47 | require 'cloudflair/api/zone/settings/prefetch_preload' 48 | require 'cloudflair/api/zone/settings/response_buffering' 49 | require 'cloudflair/api/zone/settings/rocket_loader' 50 | require 'cloudflair/api/zone/settings/security_header' 51 | require 'cloudflair/api/zone/settings/security_level' 52 | require 'cloudflair/api/zone/settings/server_side_exclude' 53 | require 'cloudflair/api/zone/settings/sort_query_string_for_cache' 54 | require 'cloudflair/api/zone/settings/ssl' 55 | require 'cloudflair/api/zone/settings/tls_client_auth' 56 | require 'cloudflair/api/zone/settings/tls_1_2_only' 57 | require 'cloudflair/api/zone/settings/tls_1_3' 58 | require 'cloudflair/api/zone/settings/true_client_ip_header' 59 | require 'cloudflair/api/zone/settings/waf' 60 | require 'cloudflair/api/zone/settings/websockets' 61 | --------------------------------------------------------------------------------