diff --git a/.byebug_history b/.byebug_history new file mode 100644 index 0000000..2ddfdf4 --- /dev/null +++ b/.byebug_history @@ -0,0 +1,132 @@ +exit +params +exit +params +exit +Object.const_get(class_name) +send(class_name.to_sym) +class_name.to_sym +class_name +c +params +exit +params.fetch("drivers") +params.fetch("drivers"0 +exit +result +c +exit +value.class +value +exit +params[attr] +params +params[attr.to_s] +attr +exit +self.send(attr) +attr +exit +self.send(attr) +value +attr +exit +collections.include?(attr) +attr +c +n +params +self.collections +self.object_values +ATTRS +exit +params + RoutificApi::Project.new(id: params.fetch(:id),name: params.fetch(:name),date: params.fetch(:date)) + 9: ) + 8: date: params.fetch(:date) + 7: name: params.fetch(:name), + 6: id: params.fetch(:id), +RoutificApi::Project.new( +exit +params +exit +result +e +exit +data.to_json +data +response +exit +job_data +exit +job_data +exit +job.fetch +job +n +data +result['job_id'] +n +c +response +exit +headers(token) +method.downcase.to_sym +nil.to_json +url(endpoint) +RestClient::Request.execute(method: method.downcase.to_sym,url: url(endpoint),data: data.to_json,headers: headers(token)) +data.to_json +data +response +token +endpoint +method +exit +Util.send_request("POST", "vrp", Routific.token, data) +exit +data +exit +data +exit +JSON.parse({'blh': 'ljl'}) +JSON.parse({'blh'=> 'ljl'}) +JSON.parse(result) +result +exit +self +attr +self.send(attr).class +attr.class +attr +exit +subject +exit +subject +exit +@date +@name +@id +@stops +@stop +exit +@stops +stops +stopes +stores +exit +@name +name +self name +set_attrs(params) +params +attrs +exit +params +attrs +exit +self.send(attr).map(&:as_json) +self.send(attr).each(&:as_json) +self.send(attr) +exit +send(attr) +attr diff --git a/.gitignore b/.gitignore index 4b3d9a3..f18f218 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ routific-*.gem # Ignore gem locked versions Gemfile.lock + +# Ignore byebug history +.byebug_history diff --git a/README.md b/README.md index 2d277ba..6c77052 100644 --- a/README.md +++ b/README.md @@ -177,3 +177,7 @@ It returns a job object with the following attibutes: - `created_at`, `finished_at`: creation and finish times - `input`: the data used for the request - `route`: a route object + +#### `routific.set_project( data )` + +Read the [platform documentation](https://routific-platform.readme.io/reference) for a full list of attributes. diff --git a/lib/errors/missing_attribute_error.rb b/lib/errors/missing_attribute_error.rb new file mode 100644 index 0000000..9da6a53 --- /dev/null +++ b/lib/errors/missing_attribute_error.rb @@ -0,0 +1,5 @@ +class MissingAttributeError < StandardError + def initialize(msg = "Attribute not set in subclass") + super + end +end diff --git a/lib/errors/not_array_error.rb b/lib/errors/not_array_error.rb new file mode 100644 index 0000000..e198571 --- /dev/null +++ b/lib/errors/not_array_error.rb @@ -0,0 +1,5 @@ +class NotArrayError < StandardError + def initialize(msg = "Not an array") + super + end +end diff --git a/lib/routific.rb b/lib/routific.rb index fd9e1e4..9db52cc 100644 --- a/lib/routific.rb +++ b/lib/routific.rb @@ -1,3 +1,7 @@ +require_relative './errors/not_array_error' +require_relative './errors/missing_attribute_error' +require_relative './routific/jsonable' +require_relative './routific/attributable' require_relative './routific/location' require_relative './routific/visit' require_relative './routific/break' @@ -6,6 +10,17 @@ require_relative './routific/way_point' require_relative './routific/options' require_relative './routific/job' +require_relative './routific/project' +require_relative './routific/driver' +require_relative './routific/stop' +require_relative './routific/setting' +require_relative './routific/project_location' +require_relative './routific/factory_helper' +require_relative './routific/project_factory' +require_relative './routific/driver_factory' +require_relative './routific/stop_factory' +require_relative './routific/setting_factory' +require_relative './routific/project_location_factory' require_relative './util' @@ -65,6 +80,11 @@ def get_route_async RoutificApi::Job.new(result["job_id"], data) end + def set_project(data) + result = Util.send_request("POST", "project", Routific.token, data, true) + RoutificApi::ProjectFactory.new(result).call + end + class << self # Sets the default access token to use def set_token(token) diff --git a/lib/routific/attributable.rb b/lib/routific/attributable.rb new file mode 100644 index 0000000..a498ced --- /dev/null +++ b/lib/routific/attributable.rb @@ -0,0 +1,58 @@ +module RoutificApi + class Attributable + include RoutificApi::Jsonable + + ATTRS = %i(values object_values collections) + def initialize(params) + ensure_attrs_set + set_attrs(params) + end + + private + + def attrs + values + object_values + collections + end + + def ensure_attrs_set + ATTRS.each do |attr| + raise MissingAttributeError unless self.respond_to?(attr) + end + end + + def set_attrs(params) + attrs.each do |attr| + set_attr(attr, params[attr.to_s]) + end + end + + def set_attr(attr, value) + define_setter(attr, value) + define_reader(attr) + set_variable(attr, value) + ensure_collection_is_array(attr, value) + end + + def ensure_collection_is_array(attr, value) + if collections.include?(attr) && value.class != Array + raise NotArrayError + end + end + + def define_setter(attr, value) + self.class.send(:define_method, "#{ attr }=".to_sym) do |value| + instance_variable_set("@" + attr.to_s, value) + end + end + + def define_reader(attr) + self.class.send(:define_method, attr.to_sym) do + instance_variable_get("@" + attr.to_s) + end + end + + def set_variable(attr, value) + self.send("#{ attr }=".to_sym, value) + end + end +end diff --git a/lib/routific/coords.rb b/lib/routific/coords.rb new file mode 100644 index 0000000..22ddee2 --- /dev/null +++ b/lib/routific/coords.rb @@ -0,0 +1,15 @@ +module RoutificApi + class Coords < Attributable + def values + [] + end + + def object_values + %(lat lng) + end + + def collections + [] + end + end +end diff --git a/lib/routific/driver.rb b/lib/routific/driver.rb new file mode 100644 index 0000000..73f9e1d --- /dev/null +++ b/lib/routific/driver.rb @@ -0,0 +1,15 @@ +module RoutificApi + class Driver < Attributable + def values + %i(name shift_start shift_end phone_number speed capacity) + end + + def object_values + %i(start_location end_location break) + end + + def collections + %i(types) + end + end +end diff --git a/lib/routific/driver_factory.rb b/lib/routific/driver_factory.rb new file mode 100644 index 0000000..46ee8c2 --- /dev/null +++ b/lib/routific/driver_factory.rb @@ -0,0 +1,25 @@ +module RoutificApi + class DriverFactory + include FactoryHelper + + attr_reader :params + def initialize(params) + @params = params + end + + def call + Driver.new( + "name" => name, + "start_location" => start_location, + "end_location" => end_location, + "shift_start" => shift_start, + "shift_end" => shift_end, + "phone_number" => phone_number, + "speed" => speed, + "capacity" => capacity, + "types" => types, + "break" => shift_break + ) + end + end +end diff --git a/lib/routific/factory_helper.rb b/lib/routific/factory_helper.rb new file mode 100644 index 0000000..69f00fa --- /dev/null +++ b/lib/routific/factory_helper.rb @@ -0,0 +1,148 @@ +module RoutificApi + module FactoryHelper + def id + params.fetch("id") + end + + def name + params.fetch("name") + end + + def date + params.fetch("date") + end + + def phone_number + params.fetch("phone_number") + end + + def email + params.fetch("email") + end + + def start_time + params.fetch("start") + end + + def end_time + params.fetch("end") + end + + + def shift_start + params.fetch("shift_start") + end + + def shift_end + params.fetch("shift_end") + end + + def duration + params.fetch("duration") + end + + def speed + params.fetch("speed") + end + + def capacity + params.fetch("capacity") + end + + def types + params.fetch("types") + end + + def load + params.fetch("load") + end + + def priority + params.fetch("priority") + end + + def notes + params.fetch("notes") + end + + def custom_notes + params.fetch("custom_notes") + end + + def shift_break + params.fetch("break") + end + + def address + params.fetch("address") + end + + def coords + params.fetch("coords") + end + + def max_stop_lateness + params.fetch("max_stop_lateness") + end + + def max_driver_overtime + params.fetch("max_driver_overtime") + end + + def shortest_distance + params.fetch("shortest_distance") + end + + def traffic + params.fetch("traffic") + end + + def strict_start + params.fetch("strict_start") + end + + def auto_balance + params.fetch("auto_balance") + end + + def default_load + params.fetch("default_load") + end + + def default_duration + params.fetch("default_duration") + end + + def location + location_factory(params.fetch("location")) + end + + def start_location + location_factory(params.fetch("start_location")) + end + + def end_location + location_factory(params.fetch("end_location")) + end + + def location_factory(params) + RoutificApi::ProjectLocationFactory.new(params).call + end + + def settings + RoutificApi::SettingFactory.new(params.fetch("settings")).call + end + + def collection_factory(type) + params.fetch("#{ type }s").map do |params| + Object + .const_get(class_name(type.capitalize)) + .new(params).call + end + end + + def class_name(name) + "RoutificApi::#{ name }Factory" + end + end +end diff --git a/lib/routific/job.rb b/lib/routific/job.rb index 52c978e..7892173 100644 --- a/lib/routific/job.rb +++ b/lib/routific/job.rb @@ -1,5 +1,5 @@ module RoutificApi - # This class represents a job returned by vrp-long + # This class represents a job returned by vrp-long class Job FIELDS = [:status, :created_at, :finished_at] attr_reader *FIELDS diff --git a/lib/routific/jsonable.rb b/lib/routific/jsonable.rb new file mode 100644 index 0000000..918ead9 --- /dev/null +++ b/lib/routific/jsonable.rb @@ -0,0 +1,35 @@ +module RoutificApi + module Jsonable + def as_json + attrs.inject({}) do |json_data, attr| + set_json(json_data, attr) + json_data + end + end + + private + + def set_json(data, attr) + return set_json_collection(data, attr) if collections.include?(attr) + return set_object_value(data, attr) if object_values.include?(attr) + set_json_value(data, attr) + end + + def set_json_value(data, attr) + data[attr.to_s] = add_attr_if_exists(attr) + end + + def set_json_collection(data, attr) + data[attr.to_s] = self.send(attr) + .map(&:as_json) + end + + def set_object_value(data, attr) + data[attr.to_s] = self.send(attr).as_json + end + + def add_attr_if_exists(attr) + self.send(attr) if self.send(attr) + end + end +end diff --git a/lib/routific/lat.rb b/lib/routific/lat.rb new file mode 100644 index 0000000..e391b54 --- /dev/null +++ b/lib/routific/lat.rb @@ -0,0 +1,4 @@ +module RoutificApi + class Lat < SimpleAttributable + end +end diff --git a/lib/routific/lng.rb b/lib/routific/lng.rb new file mode 100644 index 0000000..4b35209 --- /dev/null +++ b/lib/routific/lng.rb @@ -0,0 +1,4 @@ +module RoutificApi + class Lng < SimpleAttributable + end +end diff --git a/lib/routific/project.rb b/lib/routific/project.rb new file mode 100644 index 0000000..f12c285 --- /dev/null +++ b/lib/routific/project.rb @@ -0,0 +1,15 @@ +module RoutificApi + class Project < Attributable + def values + %i(id name date) + end + + def object_values + %i(settings) + end + + def collections + %i(drivers stops) + end + end +end diff --git a/lib/routific/project_factory.rb b/lib/routific/project_factory.rb new file mode 100644 index 0000000..9b2d698 --- /dev/null +++ b/lib/routific/project_factory.rb @@ -0,0 +1,21 @@ +module RoutificApi + class ProjectFactory + include FactoryHelper + + attr_reader :params + def initialize(params) + @params = params + end + + def call + Project.new( + "id" => id, + "name" => name, + "date" => date, + "drivers" => collection_factory("driver"), + "stops" => collection_factory("stop"), + "settings" => settings + ) + end + end +end diff --git a/lib/routific/project_location.rb b/lib/routific/project_location.rb new file mode 100644 index 0000000..5398015 --- /dev/null +++ b/lib/routific/project_location.rb @@ -0,0 +1,15 @@ +module RoutificApi + class ProjectLocation < Attributable + def values + %i(address) + end + + def object_values + %i(coords) + end + + def collections + [] + end + end +end diff --git a/lib/routific/project_location_factory.rb b/lib/routific/project_location_factory.rb new file mode 100644 index 0000000..6e98b1b --- /dev/null +++ b/lib/routific/project_location_factory.rb @@ -0,0 +1,17 @@ +module RoutificApi + class ProjectLocationFactory + include FactoryHelper + + attr_reader :params + def initialize(params) + @params = params + end + + def call + ProjectLocation.new( + "address" => address, + "coords" => coords + ) + end + end +end diff --git a/lib/routific/setting.rb b/lib/routific/setting.rb new file mode 100644 index 0000000..36ee113 --- /dev/null +++ b/lib/routific/setting.rb @@ -0,0 +1,15 @@ +module RoutificApi + class Setting < Attributable + def values + %i(max_stop_lateness max_driver_overtime shortest_distance traffic strict_start auto_balance default_load default_duration) + end + + def object_values + [] + end + + def collections + [] + end + end +end diff --git a/lib/routific/setting_factory.rb b/lib/routific/setting_factory.rb new file mode 100644 index 0000000..7f62ed7 --- /dev/null +++ b/lib/routific/setting_factory.rb @@ -0,0 +1,22 @@ +module RoutificApi + class SettingFactory + include FactoryHelper + + attr_reader :params + def initialize(params) + @params = params + end + + def call + Setting.new( + "max_stop_lateness" => max_stop_lateness, + "max_driver_overtime" => max_driver_overtime, + "shortest_distance" => shortest_distance, + "traffic" => traffic, + "strict_start" => strict_start, + "auto_balance" => auto_balance, + "default_load" => default_load, "default_duration" => default_duration + ) + end + end +end diff --git a/lib/routific/simple_attributable.rb b/lib/routific/simple_attributable.rb new file mode 100644 index 0000000..7afa32f --- /dev/null +++ b/lib/routific/simple_attributable.rb @@ -0,0 +1,19 @@ +module RoutificApi + class SimpleAttributable < Attributable + def values + %i(name) + end + + def object_values + [] + end + + def collections + [] + end + + def as_json + name + end + end +end diff --git a/lib/routific/stop.rb b/lib/routific/stop.rb new file mode 100644 index 0000000..b3aecb8 --- /dev/null +++ b/lib/routific/stop.rb @@ -0,0 +1,15 @@ +module RoutificApi + class Stop < Attributable + def values + %i(name start end duration load priority phone_number email notes) + end + + def object_values + %i(location custom_notes) + end + + def collections + %i(types) + end + end +end diff --git a/lib/routific/stop_factory.rb b/lib/routific/stop_factory.rb new file mode 100644 index 0000000..b27444c --- /dev/null +++ b/lib/routific/stop_factory.rb @@ -0,0 +1,27 @@ +module RoutificApi + class StopFactory + include FactoryHelper + + attr_reader :params + def initialize(params) + @params = params + end + + def call + Stop.new( + "name" => name, + "location" => location, + "start" => start_time, + "end" => end_time, + "duration" => duration, + "types" => types, + "load" => load, + "priority" => priority, + "phone_number" => phone_number, + "email" => email, + "notes" => notes, + "custom_notes" => custom_notes + ) + end + end +end diff --git a/lib/routific/type.rb b/lib/routific/type.rb new file mode 100644 index 0000000..a693f4c --- /dev/null +++ b/lib/routific/type.rb @@ -0,0 +1,4 @@ +module RoutificApi + class Type < SimpleAttributable + end +end diff --git a/lib/util.rb b/lib/util.rb index 6d7ac73..8da3596 100644 --- a/lib/util.rb +++ b/lib/util.rb @@ -2,7 +2,8 @@ require 'json' module Util - BASE_URL = 'https://api.routific.com/v1/' + BASE_URL = 'https://api.routific.com/v1/' + PRODUCT_URL = 'https://product-api.routific.com/v1.0/' ## # method: "GET", "POST" @@ -10,31 +11,51 @@ module Util # token: if nil, raise ArgumentError; if missing "bearer", prefix # data: only for POST requests # - def self.send_request(method, endpoint, token = nil, data = nil) - url = BASE_URL + endpoint - headers = { - content_type: :json, - accept: :json - } - headers['Authorization'] = token if token + def self.send_request(method, endpoint, token = nil, data = nil, product = false) begin - # Sends HTTP request to Routific API server - response = nil - if method == 'GET' - response = RestClient.get(url, headers) - elsif method == 'POST' - response = RestClient.post(url, data.to_json, headers) - end - - return JSON.parse(response) + params = request_params(method, url(endpoint, product), token, data) + execute_request(params) rescue => e - puts e - errorResponse = JSON.parse e.response.body - puts "Received HTTP #{e.message}: #{errorResponse["error"]}" - nil + error_response(e) end end + private + + def self.execute_request(params) + response = RestClient::Request.execute(params) + JSON.parse(response) + end + + def self.request_params(method, url_val, token, data) + {}.tap do |params| + params[:method] = method.downcase.to_sym + params[:url] = url_val + params[:payload] = data.to_json unless data == nil + params[:headers] = headers(token) + end + end + + def self.headers(token) + {}.tap do |header| + header[:content_type] = :json + header[:accept] = :json + header['Authorization'] = token if token + end + end + + def self.url(endpoint, product) + return PRODUCT_URL + endpoint if product + BASE_URL + endpoint + end + + def self.error_response(e) + puts e + errorResponse = JSON.parse e.response.body + puts "Received HTTP #{ e.message }: #{ errorResponse["error"] }" + nil + end + def self.prefix_token(token) (/bearer /.match(token).nil?) ? "bearer #{token}" : token end diff --git a/routific.gemspec b/routific.gemspec index 6ba1655..6202baf 100644 --- a/routific.gemspec +++ b/routific.gemspec @@ -7,6 +7,8 @@ Gem::Specification.new do |s| s.add_development_dependency('rspec', '~> 3.0') s.add_development_dependency('faker', '>= 1.6.2') s.add_development_dependency('dotenv', '~> 0.11') + s.add_development_dependency('rb-readline', '~> 0.5.3') + s.add_development_dependency('byebug', '~> 11.0') s.summary = 'routific API' s.description = 'Gem to use Routific API' s.email = 'support@routific.com' diff --git a/spec/attributable_spec.rb b/spec/attributable_spec.rb new file mode 100644 index 0000000..f2081d9 --- /dev/null +++ b/spec/attributable_spec.rb @@ -0,0 +1,42 @@ +require_relative './helper/spec_helper' + +describe RoutificApi::Attributable do + let(:subject) { AttributableSubclass.new(params) } + let(:params) { Factory::ATTRIBUTABLE_PARAMS } + + class AttributableSubclass < RoutificApi::Attributable + def values; %i(val_attr); end + def object_values; %i(obj_val_attr); end + def collections; %i(collection_attr); end + end + + describe "instance variables" do + it "has value" do + expect(subject.val_attr).to eq("VALUE") + end + + context "valid collections" do + it "has collections" do + expect(subject.collection_attr.class).to eq(Array) + expect(subject.collection_attr.first).to eq("COLLECTION") + end + end + + context "invalid collections" do + let(:params) { Factory::ATTRIBUTABLE_PARAMS_INVALID_COLLECTION } + + it "raises an error" do + expect { subject }.to raise_error(NotArrayError) + end + end + end + + context "attributes not set" do + it "raises a missing attribute error" do + %i(values object_values collections).each do |meth| + AttributableSubclass.class_eval("undef #{ meth }") + expect { subject }.to raise_error(MissingAttributeError) + end + end + end +end diff --git a/spec/helper/factory.rb b/spec/helper/factory.rb index 59f77b0..3d3f9df 100644 --- a/spec/helper/factory.rb +++ b/spec/helper/factory.rb @@ -52,7 +52,7 @@ class Factory VISIT_PARAMS_MULTIPLE_TYPE["type"] = MULTIPLE_TYPE VISIT_MULTIPLE_TYPE = RoutificApi::Visit.new(VISIT_ID, VISIT_PARAMS_MULTIPLE_TYPE) - # Factoru and constants for break + # Factory and constants for break BREAK_ID = Faker::Lorem.word BREAK_START = "12:00" BREAK_END = "12:30" @@ -65,6 +65,26 @@ class Factory } BREAK = RoutificApi::Break.new(BREAK_PARAMS) + # Constants for attributable + ATTRIBUTABLE_PARAMS = { + "val_attr" => "VALUE", + "obj_val_attr" => OpenStruct.new, + "collection_attr" => ["COLLECTION"] + } + + ATTRIBUTABLE_PARAMS_INVALID_COLLECTION = { + "val_attr" => "VALUE", + "obj_val_attr" => OpenStruct.new, + "collection_attr" => "COLLECTION" + } + + # Constants for jsonable + JSONABLE_PARAMS = { + "val_attr" => "VALUE", + "obj_val_attr" => OpenStruct.new(as_json: "OBJECT VALUE"), + "collection_attr" => [OpenStruct.new(as_json: "COLLECTION")] + } + # Factory and constants for vehicle VEHICLE_ID = Faker::Lorem.word VEHICLE_NAME = Faker::Lorem.word @@ -193,4 +213,71 @@ class Factory "output" => ROUTE_PARAMS_STRING } JOB = RoutificApi::Job.new(JOB_ID, JOB_INPUT) + + # Constants for ProjectFactory + PROJECT_ID = Faker::Lorem.word + PROJECT_NAME = Faker::Lorem.word + DRIVER_NAME = Faker::Lorem.word + PROJECT_DATA = { + "name" => PROJECT_NAME, + "date" => DateTime.now.strftime('%Y-%m-%d'), + "drivers" => [{ + "name" => DRIVER_NAME, + "start_location" => { + "address" => "555 west hastings, vancouver bc, canada", + "coords" => { + "lat" => 49.2847001, + "lng" => -123.1141236 + } + }, + "end_location" => { + "address" => "555 west hastings, vancouver bc, canada", + "coords" => { + "lat" => 49.2847001, + "lng" => -123.1141236 + } + }, + "shift_start" => "09:00", + "shift_end" => "17:00", + "phone_number" => "+16042597686", + "speed" => 1, + "capacity" => 10, + "types" => ["a", "b"], + "break" => { + "start" => "12:00", + "end" => "13:00" + } + }], + "stops" => [{ + "name" => "Jane Doe", + "location" => { + "address" => "2148 Main St, Vancouver, BC V5T 3C5", + "coords" => { + "lat" => 49.2657634, + "lng" => -123.1004459 + } + }, + "start" => "10:00", + "end" => "11:00", + "duration" => 20, + "types" => ["a"], + "load" => 1, + "priority" => true, + "phone_number" => "+16046204589", + "email" => "jane@doe.com", + "notes" => "Press 304 at buzzer.", + "custom_notes" => {} + }], + "settings" => { + "max_stop_lateness" => 320, + "max_driver_overtime" => 320, + "shortest_distance" => true, + "traffic" => 1.4, + "strict_start" => true, + "auto_balance" => true, + "default_load" => 1, + "default_duration" => 10 + } + } + PROJECT_FACTORY_PARAMS = PROJECT_DATA.merge("id" => PROJECT_ID) end diff --git a/spec/helper/spec_helper.rb b/spec/helper/spec_helper.rb index 65b0b39..e1c60ca 100644 --- a/spec/helper/spec_helper.rb +++ b/spec/helper/spec_helper.rb @@ -6,6 +6,10 @@ require 'dotenv' Dotenv.load +require 'byebug' + +require 'date' + require 'routific' require_relative './factory' diff --git a/spec/jsonable_spec.rb b/spec/jsonable_spec.rb new file mode 100644 index 0000000..a9abb64 --- /dev/null +++ b/spec/jsonable_spec.rb @@ -0,0 +1,29 @@ +require_relative './helper/spec_helper' + +describe RoutificApi::Jsonable do + let(:subject) { JsonableSubclass.new(params) } + let(:params) { Factory::JSONABLE_PARAMS } + + class JsonableSubclass < RoutificApi::Attributable + include RoutificApi::Jsonable + def values; %i(val_attr); end + def object_values; %i(obj_val_attr); end + def collections; %i(collection_attr); end + end + + describe "#as_json" do + let(:result) { subject.as_json } + + it "sets the value" do + expect(result["val_attr"]).to eq("VALUE") + end + + it "sets the collection's as_json value" do + expect(result["collection_attr"].first).to eq("COLLECTION") + end + + it "sets the object value's as_json value" do + expect(result["obj_val_attr"]).to eq("OBJECT VALUE") + end + end +end diff --git a/spec/project_factory_spec.rb b/spec/project_factory_spec.rb new file mode 100644 index 0000000..b1629dc --- /dev/null +++ b/spec/project_factory_spec.rb @@ -0,0 +1,39 @@ +require_relative './helper/spec_helper' + +RSpec.describe RoutificApi::ProjectFactory do + let(:subject) { described_class.new(params) } + let(:params) { Factory::PROJECT_FACTORY_PARAMS } + + describe "#call" do + let(:result) { subject.call } + + it "returns a project" do + expect(result.class).to eq(RoutificApi::Project) + end + + describe "#drivers" do + it "is an array of Driver" do + expect(result.drivers.first.class).to eq(RoutificApi::Driver) + end + + describe "locations" do + it "is an instance of ProjectLocation" do + expect(result.drivers.first.start_location.class).to eq(RoutificApi::ProjectLocation) + expect(result.drivers.first.end_location.class).to eq(RoutificApi::ProjectLocation) + end + end + end + + describe "#stops" do + it "is an array of Stop" do + expect(result.stops.first.class).to eq(RoutificApi::Stop) + end + end + + describe "#settings" do + it "is an instance of Setting" do + expect(result.settings.class).to eq(RoutificApi::Setting) + end + end + end +end diff --git a/spec/routific_spec.rb b/spec/routific_spec.rb index 9633844..72410e1 100644 --- a/spec/routific_spec.rb +++ b/spec/routific_spec.rb @@ -162,6 +162,15 @@ def set_visit_and_vehicle(routific) expect(job.route).to be_instance_of(RoutificApi::Route) end end + + describe "#set_project" do + let(:result) { routific.set_project(data) } + let(:data) { Factory::PROJECT_DATA } + + it "returns a Project instance" do + expect(result).to be_instance_of(RoutificApi::Project) + end + end end describe "class methods" do diff --git a/spec/util_spec.rb b/spec/util_spec.rb new file mode 100644 index 0000000..b20c14e --- /dev/null +++ b/spec/util_spec.rb @@ -0,0 +1,59 @@ +require_relative './helper/spec_helper' + +RSpec.describe Util do + let(:subject) { Util } + let(:endpoint) { "endpoint" } + let(:url) { "#{ Util::BASE_URL }#{ endpoint }" } + let(:headers) { "HEADERS" } + let(:data) { { key: "RESULT" } } + + before do + expect(subject).to receive(:headers) + .and_return(headers) + end + + describe ".send_request" do + context "GET" do + let(:method) { "GET" } + let(:result) { subject.send_request(method, endpoint ) } + + before do + expect(RestClient::Request).to receive(:execute).with(method: :get, url: url, headers: headers) + .and_return(data.to_json) + end + + it "passes the method to RestClient" do + expect(result['key']).to eq("RESULT") + end + end + + context "POST" do + let(:method) { "POST" } + let(:result) { subject.send_request(method, endpoint, nil, data ) } + + before do + expect(RestClient::Request).to receive(:execute).with(method: :post, url: url, payload: data.to_json, headers: headers) + .and_return(data.to_json) + end + + it "passes the method to RestClient" do + expect(result['key']).to eq("RESULT") + end + end + + context "product API" do + let(:method) { "POST" } + let(:result) { subject.send_request(method, endpoint, nil, data, true ) } + let(:url) { "#{ Util::PRODUCT_URL }#{ endpoint }" } + + before do + expect(RestClient::Request).to receive(:execute).with(method: :post, url: url, payload: data.to_json, headers: headers) + .and_return(data.to_json) + end + + it "passes the method to RestClient" do + expect(result['key']).to eq("RESULT") + end + end + end +end