From 96997c48baf7fcc90bbb83f822182ab10c04e96b Mon Sep 17 00:00:00 2001 From: Divya Date: Tue, 30 Oct 2018 15:32:02 -0700 Subject: [PATCH 01/17] Created new project Api-muncher --- .gitignore | 27 ++ .ruby-version | 1 + Gemfile | 81 +++++ Gemfile.lock | 279 ++++++++++++++++++ Guardfile | 9 + README.md | 107 +------ Rakefile | 6 + app/assets/config/manifest.js | 3 + app/assets/images/.keep | 0 app/assets/javascripts/application.js | 20 ++ app/assets/javascripts/cable.js | 13 + app/assets/javascripts/channels/.keep | 0 app/assets/stylesheets/application.scss | 18 ++ app/channels/application_cable/channel.rb | 4 + app/channels/application_cable/connection.rb | 4 + app/controllers/application_controller.rb | 2 + app/controllers/concerns/.keep | 0 app/helpers/application_helper.rb | 2 + app/jobs/application_job.rb | 2 + app/mailers/application_mailer.rb | 4 + app/models/application_record.rb | 3 + app/models/concerns/.keep | 0 app/views/layouts/application.html.erb | 15 + app/views/layouts/mailer.html.erb | 13 + app/views/layouts/mailer.text.erb | 1 + bin/bundle | 3 + bin/rails | 9 + bin/rake | 9 + bin/setup | 36 +++ bin/spring | 17 ++ bin/update | 31 ++ bin/yarn | 11 + config.ru | 5 + config/application.rb | 25 ++ config/boot.rb | 4 + config/cable.yml | 10 + config/credentials.yml.enc | 1 + config/database.yml | 85 ++++++ config/environment.rb | 5 + config/environments/development.rb | 61 ++++ config/environments/production.rb | 94 ++++++ config/environments/test.rb | 46 +++ .../application_controller_renderer.rb | 8 + config/initializers/assets.rb | 14 + config/initializers/backtrace_silencers.rb | 7 + .../initializers/content_security_policy.rb | 25 ++ config/initializers/cookies_serializer.rb | 5 + .../initializers/filter_parameter_logging.rb | 4 + config/initializers/inflections.rb | 16 + config/initializers/mime_types.rb | 4 + config/initializers/wrap_parameters.rb | 14 + config/locales/en.yml | 33 +++ config/puma.rb | 34 +++ config/routes.rb | 3 + config/spring.rb | 6 + config/storage.yml | 34 +++ db/seeds.rb | 7 + lib/assets/.keep | 0 lib/tasks/.keep | 0 log/.keep | 0 package.json | 5 + public/404.html | 67 +++++ public/422.html | 67 +++++ public/500.html | 66 +++++ public/apple-touch-icon-precomposed.png | 0 public/apple-touch-icon.png | 0 public/favicon.ico | 0 public/robots.txt | 1 + storage/.keep | 0 test/application_system_test_case.rb | 5 + test/controllers/.keep | 0 test/fixtures/.keep | 0 test/fixtures/files/.keep | 0 test/helpers/.keep | 0 test/integration/.keep | 0 test/mailers/.keep | 0 test/models/.keep | 0 test/system/.keep | 0 test/test_helper.rb | 24 ++ tmp/.keep | 0 vendor/.keep | 0 81 files changed, 1421 insertions(+), 94 deletions(-) create mode 100644 .gitignore create mode 100644 .ruby-version create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Guardfile create mode 100644 Rakefile create mode 100644 app/assets/config/manifest.js create mode 100644 app/assets/images/.keep create mode 100644 app/assets/javascripts/application.js create mode 100644 app/assets/javascripts/cable.js create mode 100644 app/assets/javascripts/channels/.keep create mode 100644 app/assets/stylesheets/application.scss create mode 100644 app/channels/application_cable/channel.rb create mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/concerns/.keep create mode 100644 app/helpers/application_helper.rb create mode 100644 app/jobs/application_job.rb create mode 100644 app/mailers/application_mailer.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/views/layouts/application.html.erb create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100755 bin/bundle create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/setup create mode 100755 bin/spring create mode 100755 bin/update create mode 100755 bin/yarn create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/cable.yml create mode 100644 config/credentials.yml.enc create mode 100644 config/database.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/application_controller_renderer.rb create mode 100644 config/initializers/assets.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/content_security_policy.rb create mode 100644 config/initializers/cookies_serializer.rb create mode 100644 config/initializers/filter_parameter_logging.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/puma.rb create mode 100644 config/routes.rb create mode 100644 config/spring.rb create mode 100644 config/storage.yml create mode 100644 db/seeds.rb create mode 100644 lib/assets/.keep create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 package.json create mode 100644 public/404.html create mode 100644 public/422.html create mode 100644 public/500.html create mode 100644 public/apple-touch-icon-precomposed.png create mode 100644 public/apple-touch-icon.png create mode 100644 public/favicon.ico create mode 100644 public/robots.txt create mode 100644 storage/.keep create mode 100644 test/application_system_test_case.rb create mode 100644 test/controllers/.keep create mode 100644 test/fixtures/.keep create mode 100644 test/fixtures/files/.keep create mode 100644 test/helpers/.keep create mode 100644 test/integration/.keep create mode 100644 test/mailers/.keep create mode 100644 test/models/.keep create mode 100644 test/system/.keep create mode 100644 test/test_helper.rb create mode 100644 tmp/.keep create mode 100644 vendor/.keep diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..18b43c9cd --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore uploaded files in development +/storage/* +!/storage/.keep + +/node_modules +/yarn-error.log + +/public/assets +.byebug_history + +# Ignore master key for decrypting credentials and more. +/config/master.key diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 000000000..25c81fe39 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-2.5.1 \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..6219256bd --- /dev/null +++ b/Gemfile @@ -0,0 +1,81 @@ +source 'https://rubygems.org' +git_source(:github) { |repo| "https://github.com/#{repo}.git" } + +ruby '2.5.1' + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '~> 5.2.1' +# Use postgresql as the database for Active Record +gem 'pg', '>= 0.18', '< 2.0' +# Use Puma as the app server +gem 'puma', '~> 3.11' +# Use SCSS for stylesheets +gem 'sass-rails', '~> 5.0' +# Use Uglifier as compressor for JavaScript assets +gem 'uglifier', '>= 1.3.0' +# See https://github.com/rails/execjs#readme for more supported runtimes +# gem 'mini_racer', platforms: :ruby + +# Use CoffeeScript for .coffee assets and views +# gem 'coffee-rails', '~> 4.2' +# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks +gem 'turbolinks', '~> 5' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +gem 'jbuilder', '~> 2.5' +# Use Redis adapter to run Action Cable in production +# gem 'redis', '~> 4.0' +# Use ActiveModel has_secure_password +# gem 'bcrypt', '~> 3.1.7' + +# Use ActiveStorage variant +# gem 'mini_magick', '~> 4.8' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +# Reduces boot times through caching; required in config/boot.rb +gem 'bootsnap', '>= 1.1.0', require: false + +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] +end + +group :development do + # Access an interactive console on exception pages or by calling 'console' anywhere in the code. + gem 'web-console', '>= 3.3.0' + gem 'listen', '>= 3.0.5', '< 3.2' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' + gem 'spring-watcher-listen', '~> 2.0.0' +end + +group :test do + # Adds support for Capybara system testing and selenium driver + gem 'capybara', '>= 2.15' + gem 'selenium-webdriver' + # Easy installation and use of chromedriver to run system tests with Chrome + gem 'chromedriver-helper' +end + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +gem 'jquery-rails' +gem 'jquery-turbolinks' +gem 'bootstrap', '~> 4.1.3' +group :development, :test do + gem 'pry-rails' +end + +group :development do + gem 'better_errors' + gem 'binding_of_caller' + gem 'guard' + gem 'guard-minitest' +end + +group :test do + gem 'minitest-rails' + gem 'minitest-reporters' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..81ff1b0a8 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,279 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.2.1) + actionpack (= 5.2.1) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailer (5.2.1) + actionpack (= 5.2.1) + actionview (= 5.2.1) + activejob (= 5.2.1) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.2.1) + actionview (= 5.2.1) + activesupport (= 5.2.1) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.2.1) + activesupport (= 5.2.1) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.2.1) + activesupport (= 5.2.1) + globalid (>= 0.3.6) + activemodel (5.2.1) + activesupport (= 5.2.1) + activerecord (5.2.1) + activemodel (= 5.2.1) + activesupport (= 5.2.1) + arel (>= 9.0) + activestorage (5.2.1) + actionpack (= 5.2.1) + activerecord (= 5.2.1) + marcel (~> 0.3.1) + activesupport (5.2.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + ansi (1.5.0) + archive-zip (0.11.0) + io-like (~> 0.3.0) + arel (9.0.0) + autoprefixer-rails (9.3.1) + execjs + better_errors (2.5.0) + coderay (>= 1.0.0) + erubi (>= 1.0.0) + rack (>= 0.9.0) + bindex (0.5.0) + binding_of_caller (0.8.0) + debug_inspector (>= 0.0.1) + bootsnap (1.3.2) + msgpack (~> 1.0) + bootstrap (4.1.3) + autoprefixer-rails (>= 6.0.3) + popper_js (>= 1.12.9, < 2) + sass (>= 3.5.2) + builder (3.2.3) + byebug (10.0.2) + capybara (3.10.0) + addressable + mini_mime (>= 0.1.3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (~> 1.2) + xpath (~> 3.2) + childprocess (0.9.0) + ffi (~> 1.0, >= 1.0.11) + chromedriver-helper (2.1.0) + archive-zip (~> 0.10) + nokogiri (~> 1.8) + coderay (1.1.2) + concurrent-ruby (1.0.5) + crass (1.0.4) + debug_inspector (0.0.3) + erubi (1.7.1) + execjs (2.7.0) + ffi (1.9.25) + formatador (0.2.5) + globalid (0.4.1) + activesupport (>= 4.2.0) + guard (2.14.2) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-compat (1.2.1) + guard-minitest (2.4.6) + guard-compat (~> 1.2) + minitest (>= 3.0) + i18n (1.1.1) + concurrent-ruby (~> 1.0) + io-like (0.3.0) + jbuilder (2.7.0) + activesupport (>= 4.2.0) + multi_json (>= 1.2) + jquery-rails (4.3.3) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) + jquery-turbolinks (2.1.0) + railties (>= 3.1.0) + turbolinks + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + loofah (2.2.3) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + lumberjack (1.0.13) + mail (2.7.1) + mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) + method_source (0.9.0) + mimemagic (0.3.2) + mini_mime (1.0.1) + mini_portile2 (2.3.0) + minitest (5.11.3) + minitest-rails (3.0.0) + minitest (~> 5.8) + railties (~> 5.0) + minitest-reporters (1.3.5) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + msgpack (1.2.4) + multi_json (1.13.1) + nenv (0.3.0) + nio4r (2.3.1) + nokogiri (1.8.5) + mini_portile2 (~> 2.3.0) + notiffany (0.1.1) + nenv (~> 0.1) + shellany (~> 0.0) + pg (1.1.3) + popper_js (1.14.3) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry-rails (0.3.6) + pry (>= 0.10.4) + public_suffix (3.0.3) + puma (3.12.0) + rack (2.0.5) + rack-test (1.1.0) + rack (>= 1.0, < 3) + rails (5.2.1) + actioncable (= 5.2.1) + actionmailer (= 5.2.1) + actionpack (= 5.2.1) + actionview (= 5.2.1) + activejob (= 5.2.1) + activemodel (= 5.2.1) + activerecord (= 5.2.1) + activestorage (= 5.2.1) + activesupport (= 5.2.1) + bundler (>= 1.3.0) + railties (= 5.2.1) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.4) + loofah (~> 2.2, >= 2.2.2) + railties (5.2.1) + actionpack (= 5.2.1) + activesupport (= 5.2.1) + method_source + rake (>= 0.8.7) + thor (>= 0.19.0, < 2.0) + rake (12.3.1) + rb-fsevent (0.10.3) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + regexp_parser (1.2.0) + ruby-progressbar (1.10.0) + ruby_dep (1.5.0) + rubyzip (1.2.2) + sass (3.6.0) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sass-rails (5.0.7) + railties (>= 4.0.0, < 6) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) + selenium-webdriver (3.14.1) + childprocess (~> 0.5) + rubyzip (~> 1.2, >= 1.2.2) + shellany (0.0.1) + spring (2.0.2) + activesupport (>= 4.2) + spring-watcher-listen (2.0.1) + listen (>= 2.7, < 4.0) + spring (>= 1.2, < 3.0) + sprockets (3.7.2) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.1) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.20.0) + thread_safe (0.3.6) + tilt (2.0.8) + turbolinks (5.2.0) + turbolinks-source (~> 5.2) + turbolinks-source (5.2.0) + tzinfo (1.2.5) + thread_safe (~> 0.1) + uglifier (4.1.19) + execjs (>= 0.3.0, < 3) + web-console (3.7.0) + actionview (>= 5.0) + activemodel (>= 5.0) + bindex (>= 0.4.0) + railties (>= 5.0) + websocket-driver (0.7.0) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.3) + xpath (3.2.0) + nokogiri (~> 1.8) + +PLATFORMS + ruby + +DEPENDENCIES + better_errors + binding_of_caller + bootsnap (>= 1.1.0) + bootstrap (~> 4.1.3) + byebug + capybara (>= 2.15) + chromedriver-helper + guard + guard-minitest + jbuilder (~> 2.5) + jquery-rails + jquery-turbolinks + listen (>= 3.0.5, < 3.2) + minitest-rails + minitest-reporters + pg (>= 0.18, < 2.0) + pry-rails + puma (~> 3.11) + rails (~> 5.2.1) + sass-rails (~> 5.0) + selenium-webdriver + spring + spring-watcher-listen (~> 2.0.0) + turbolinks (~> 5) + tzinfo-data + uglifier (>= 1.3.0) + web-console (>= 3.3.0) + +RUBY VERSION + ruby 2.5.1p57 + +BUNDLED WITH + 1.16.2 diff --git a/Guardfile b/Guardfile new file mode 100644 index 000000000..e34f706f4 --- /dev/null +++ b/Guardfile @@ -0,0 +1,9 @@ +guard :minitest, autorun: false, spring: true do + watch(%r{^app/(.+).rb$}) { |m| "test/#{m[1]}_test.rb" } + watch(%r{^app/controllers/application_controller.rb$}) { 'test/controllers' } + watch(%r{^app/controllers/(.+)_controller.rb$}) { |m| "test/integration/#{m[1]}_test.rb" } + watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" } + watch(%r{^lib/(.+).rb$}) { |m| "test/lib/#{m[1]}_test.rb" } + watch(%r{^test/.+_test.rb$}) + watch(%r{^test/test_helper.rb$}) { 'test' } +end diff --git a/README.md b/README.md index d76b81007..7db80e4ca 100644 --- a/README.md +++ b/README.md @@ -1,105 +1,24 @@ -# API Muncher: Recipe API Consumer +# README -## At a Glance +This README would normally document whatever steps are necessary to get the +application up and running. -- Individual, [stage 2](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/rule-of-three.md#stage-2) project -- Due **before class, Mon 11/5** +Things you may want to cover: -## Learning Goals: +* Ruby version -- Configure an API for consumption -- Create authenticated API requests using HTTParty -- Consume JSON responses from an API -- Map response to application-specific data -- Separate API logic from application logic +* System dependencies -## Objective +* Configuration -We will create a web application that displays recipes based on a search term. We will utilize an API from Edamam called the [Recipe Search API](https://developer.edamam.com/edamam-recipe-api). +* Database creation -## Getting Started +* Database initialization -Before you start writing _any_ code: +* How to run the test suite -- Explore the API documentation to become familiar with the request(s) you can make -- Create a Trello Board listing the features you will need to add and use it to track the progress of your app. +* Services (job queues, cache servers, search engines, etc.) -Once you've explored the API docs, this project: +* Deployment instructions -- requires you to create a Rails application - - conform to Rails conventions on naming and inflection - - by using `rails new .` you will create a new rails app _inside_ of the fork folder instead of creating a _new_ folder for your rails app - - [Set `local: true` as default for `form_with` in Rails 5](https://stackoverflow.com/questions/47822826/set-local-true-as-default-for-form-with-in-rails-5/51666415#51666415) -- Use better_errors for debugging purposes -- Deploy your completed app to Heroku - - -## Requirements - -### Search - -- As a user, when I can type a search term into a text input and submit it, then the web app: - - Makes a request to the Edamam Recipe API using the search term - - Displays the results in a list - -### List View - -- As a user, when I look at the list of recipes that were the result of a search, then the web app: - - shows a **paged** list of recipes for a given search term, _ten at a time_ - - shows the name of the recipe and the corresponding photo - - shows next to within each listed recipe a link to that recipe's detail page - -### Show View - -- As a user, when I look at a recipe's detail page, then the web app shows the following details about the individual recipe: - - Name - - Link to the original recipe (opens in a new tab) - - Ingredients - - Dietary information - -### Non-functional Requirements - -- Follow the requirements of attribution to Edamam, as required by their Terms and Conditions - - [Official documentation from Edamam on attribution](https://developer.edamam.com/attribution) -- Create thorough tests for your any API Wrappers, classes, and controllers using VCR -- As a user, when I interact with the site and there is a problem, then I can see an error message detailing what the problem is and what I should do - - As a user, when I put in an incorrect parameter for an individual recipe in the browser's address bar, then the site reports a friendly error explaining that this recipe doesn't exist, and doesn't show an exception - -## Important Notes - -- How will you go from a list of recipes pulled down from an API, to being able to view a specific recipe in detail? Take time to consider your answer, write down the steps, and make a plan. Then, look at the API documentation to understand the detail of how you will execute it. Use Postman and your debugging skills to aggressively check what your requests look like in order to get specific recipe detail data. **Edamam's API is not RESTful**; this is not trivial. You'll have to use some clever code to get this to work! Be patient, and you'll get there. -- Using this API as a developer limits the number of API calls in a month to 5000. This means that we must try to minimize API calls for testing purposes as much as possible, to ensure you do not exceed this number of API calls in the one week of development we have. - -## Optional Enhancements - -- Keep track of most recent search terms and allow users to return to those searches -- Implement an OAuth strategy using Google - - Allow users to save recipes to a "favorites" section that they can return to -- Provide checkboxes or other controls to limit the search to options such as: - - Peanut Free - - Soy Free - - High Protein - - Etc - -### Optional Wireframes - -You have creative control over the design and layout of this project. Below are optional wireframes you may use. It is not a requirement that you do. - -### Homepage - - ![Splash Page Wireframe](assets/Muncher_splash_wireframe.png ) - -### Results Page - - ![Results Page Wireframe](assets/muncher_results_wireframe.png ) - -### Recipe Show Page - - ![Results Page Wireframe](assets/muncher_recipe_wireframe.png ) - - -Can you make your layout responsive? When the screen width shrinks to a medium screen, have a row with only two recipes. On a small screen width, have only a single recipe per line. - -## What Instructors Are Looking For - -Check out the [feedback template](feedback.md) which lists the items instructors will be looking for as they evaluate your project. +* ... diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..e85f91391 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative 'config/application' + +Rails.application.load_tasks diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 000000000..b16e53d6d --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1,3 @@ +//= link_tree ../images +//= link_directory ../javascripts .js +//= link_directory ../stylesheets .css diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 000000000..4f73c21a7 --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,20 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's +// vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. JavaScript code in this file should be added after the last require_* statement. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. + //= require jquery3 + //= require popper + //= require bootstrap-sprockets + +// +//= require rails-ujs +//= require activestorage +//= require turbolinks +//= require_tree . diff --git a/app/assets/javascripts/cable.js b/app/assets/javascripts/cable.js new file mode 100644 index 000000000..739aa5f02 --- /dev/null +++ b/app/assets/javascripts/cable.js @@ -0,0 +1,13 @@ +// Action Cable provides the framework to deal with WebSockets in Rails. +// You can generate new channels where WebSocket features live using the `rails generate channel` command. +// +//= require action_cable +//= require_self +//= require_tree ./channels + +(function() { + this.App || (this.App = {}); + + App.cable = ActionCable.createConsumer(); + +}).call(this); diff --git a/app/assets/javascripts/channels/.keep b/app/assets/javascripts/channels/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss new file mode 100644 index 000000000..8b1701e58 --- /dev/null +++ b/app/assets/stylesheets/application.scss @@ -0,0 +1,18 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's + * vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. + * + */ + +/* Custom bootstrap variables must be set or imported *before* bootstrap. */ +@import "bootstrap"; +/* Import scss content */ +@import "**/*"; diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 000000000..d67269728 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 000000000..0ff5442f4 --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 000000000..09705d12a --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::Base +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 000000000..de6be7945 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 000000000..a009ace51 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 000000000..286b2239d --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..10a4cba84 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 000000000..f2e0d8faa --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,15 @@ + + + + ApiMuncher + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> + <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 000000000..cbd34d2e9 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 000000000..37f0bddbd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 000000000..f19acf5b5 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 000000000..5badb2fde --- /dev/null +++ b/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 000000000..d87d5f578 --- /dev/null +++ b/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 000000000..94fd4d797 --- /dev/null +++ b/bin/setup @@ -0,0 +1,36 @@ +#!/usr/bin/env ruby +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:setup' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/bin/spring b/bin/spring new file mode 100755 index 000000000..fb2ec2ebb --- /dev/null +++ b/bin/spring @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) + spring = lockfile.specs.detect { |spec| spec.name == "spring" } + if spring + Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path + gem 'spring', spring.version + require 'spring/binstub' + end +end diff --git a/bin/update b/bin/update new file mode 100755 index 000000000..58bfaed51 --- /dev/null +++ b/bin/update @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/bin/yarn b/bin/yarn new file mode 100755 index 000000000..460dd565b --- /dev/null +++ b/bin/yarn @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +APP_ROOT = File.expand_path('..', __dir__) +Dir.chdir(APP_ROOT) do + begin + exec "yarnpkg", *ARGV + rescue Errno::ENOENT + $stderr.puts "Yarn executable was not detected in the system." + $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" + exit 1 + end +end diff --git a/config.ru b/config.ru new file mode 100644 index 000000000..f7ba0b527 --- /dev/null +++ b/config.ru @@ -0,0 +1,5 @@ +# This file is used by Rack-based servers to start the application. + +require_relative 'config/environment' + +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 000000000..0b5eed283 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,25 @@ +require_relative 'boot' + +require 'rails/all' + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module ApiMuncher + class Application < Rails::Application + config.generators do |g| + # Force new test files to be generated in the minitest-spec style + g.test_framework :minitest, spec: true + # Always use .js files, never .coffee + g.javascript_engine :js + end + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 5.2 + + # Settings in config/environments/* take precedence over those specified here. + # Application configuration can go into files in config/initializers + # -- all .rb files in that directory are automatically loaded after loading + # the framework and any gems in your application. + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 000000000..b9e460cef --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,4 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. +require 'bootsnap/setup' # Speed up boot time by caching expensive operations. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..cf3ce7efa --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: api-muncher_production diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc new file mode 100644 index 000000000..d667e9a54 --- /dev/null +++ b/config/credentials.yml.enc @@ -0,0 +1 @@ +MvEopeg/xxqih9SCY2NcA0a13MGe+QL/+jSuzX4GaREzqJsatLskcr2+cFLk6knJLykIp39e6N5/5z1/AQi/aDRDOQnLNMHnbGA5EoipdcfhP5c5z8v04Yln2Ft7R3IGSOjj6kAdsDLGRmhr/XcIlKilQ9PJyIIZl/iuMHa1vHZH5LYfk5ojLSGMFnxkLH5nrCQqPpQELetZxs4CZpdASBlcLIHNYyfiPppTFVT1WCSDgotlYk556RIaDVt3MOXpxEraqMzhPlxLULzP4gBaVLf1tkfnq5GPEc4gx+VGNYQ8Yuh6ZvLBHQarC1i2mRWdJBCApyKj0e3gge1rYMM8PQF+A7drs7bu32C0zDTAUq1wLbnSwf6bmdqOQw4rgmGNQLLrO+PqWeqwOo9a0EUO7J7JmvgcFAxvB9FA--YLbpPSEbvSMBQ94Z--ssoyHSWt8VhUccxDj0KfFw== \ No newline at end of file diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 000000000..4cb63a555 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,85 @@ +# PostgreSQL. Versions 9.1 and up are supported. +# +# Install the pg driver: +# gem install pg +# On OS X with Homebrew: +# gem install pg -- --with-pg-config=/usr/local/bin/pg_config +# On OS X with MacPorts: +# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config +# On Windows: +# gem install pg +# Choose the win32 build. +# Install PostgreSQL and put its /bin directory on your path. +# +# Configure Using Gemfile +# gem 'pg' +# +default: &default + adapter: postgresql + encoding: unicode + # For details on connection pooling, see Rails configuration guide + # http://guides.rubyonrails.org/configuring.html#database-pooling + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + +development: + <<: *default + database: api-muncher_development + + # The specified database role being used to connect to postgres. + # To create additional roles in postgres see `$ createuser --help`. + # When left blank, postgres will use the default role. This is + # the same name as the operating system user that initialized the database. + #username: api-muncher + + # The password associated with the postgres role (username). + #password: + + # Connect on a TCP socket. Omitted by default since the client uses a + # domain socket that doesn't need configuration. Windows does not have + # domain sockets, so uncomment these lines. + #host: localhost + + # The TCP port the server listens on. Defaults to 5432. + # If your server runs on a different port number, change accordingly. + #port: 5432 + + # Schema search path. The server defaults to $user,public + #schema_search_path: myapp,sharedapp,public + + # Minimum log levels, in increasing order: + # debug5, debug4, debug3, debug2, debug1, + # log, notice, warning, error, fatal, and panic + # Defaults to warning. + #min_messages: notice + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: api-muncher_test + +# As with config/secrets.yml, you never want to store sensitive information, +# like your database password, in your source code. If your source code is +# ever seen by anyone, they now have access to your database. +# +# Instead, provide the password as a unix environment variable when you boot +# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database +# for a full rundown on how to provide these environment variables in a +# production deployment. +# +# On Heroku and other platform providers, you may have a full connection URL +# available as an environment variable. For example: +# +# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" +# +# You can use this database configuration with: +# +# production: +# url: <%= ENV['DATABASE_URL'] %> +# +production: + <<: *default + database: api-muncher_production + username: api-muncher + password: <%= ENV['API-MUNCHER_DATABASE_PASSWORD'] %> diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 000000000..426333bb4 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative 'application' + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 000000000..1311e3e4e --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,61 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + # Run rails dev:cache to toggle caching. + if Rails.root.join('tmp', 'caching-dev.txt').exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{2.days.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Store uploaded files on the local file system (see config/storage.yml for options) + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Suppress logger output for asset requests. + config.assets.quiet = true + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true + + # Use an evented file watcher to asynchronously detect changes in source code, + # routes, locales, etc. This feature depends on the listen gem. + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 000000000..1d8a23cbf --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,94 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Store uploaded files on the local file system (see config/storage.yml for options) + config.active_storage.service = :local + + # Mount Action Cable outside main process or domain + # config.action_cable.mount_path = nil + # config.action_cable.url = 'wss://example.com/cable' + # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment) + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "api-muncher_#{Rails.env}" + + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 000000000..0a38fd3ce --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,46 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{1.hour.to_i}" + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory + config.active_storage.service = :test + + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100644 index 000000000..89d2efab2 --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 000000000..4b828e80c --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = '1.0' + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path +# Add Yarn node_modules folder to the asset load path. +Rails.application.config.assets.paths << Rails.root.join('node_modules') + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w( admin.js admin.css ) diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 000000000..59385cdf3 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 000000000..d3bcaa5ec --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https + +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end + +# If you are using UJS then enable automatic nonce generation +# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } + +# Report CSP violations to a specified URI +# For further information see the following documentation: +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# Rails.application.config.content_security_policy_report_only = true diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb new file mode 100644 index 000000000..5a6a32d37 --- /dev/null +++ b/config/initializers/cookies_serializer.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. + +# Specify a serializer for the signed and encrypted cookie jars. +# Valid options are :json, :marshal, and :hybrid. +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 000000000..4a994e1e7 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 000000000..ac033bf9d --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 000000000..dc1899682 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 000000000..bbfc3961b --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 000000000..decc5a857 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,33 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# The following keys must be escaped otherwise they will not be retrieved by +# the default I18n backend: +# +# true, false, on, off, yes, no +# +# Instead, surround them with single quotes. +# +# en: +# 'true': 'foo' +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 000000000..a5eccf816 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,34 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked webserver processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. +# +# preload_app! + +# Allow puma to be restarted by `rails restart` command. +plugin :tmp_restart diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 000000000..787824f88 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,3 @@ +Rails.application.routes.draw do + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html +end diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 000000000..9fa7863f9 --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w[ + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +].each { |path| Spring.watch(path) } diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 000000000..d32f76e8f --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket + +# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 000000000..1beea2acc --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). +# +# Examples: +# +# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) +# Character.create(name: 'Luke', movie: movies.first) diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/log/.keep b/log/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/package.json b/package.json new file mode 100644 index 000000000..5da55eadc --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "name": "api-muncher", + "private": true, + "dependencies": {} +} diff --git a/public/404.html b/public/404.html new file mode 100644 index 000000000..2be3af26f --- /dev/null +++ b/public/404.html @@ -0,0 +1,67 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/422.html b/public/422.html new file mode 100644 index 000000000..c08eac0d1 --- /dev/null +++ b/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/500.html b/public/500.html new file mode 100644 index 000000000..78a030af2 --- /dev/null +++ b/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png new file mode 100644 index 000000000..e69de29bb diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 000000000..e69de29bb diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 000000000..e69de29bb diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 000000000..37b576a4a --- /dev/null +++ b/public/robots.txt @@ -0,0 +1 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/storage/.keep b/storage/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb new file mode 100644 index 000000000..d19212abd --- /dev/null +++ b/test/application_system_test_case.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :selenium, using: :chrome, screen_size: [1400, 1400] +end diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/.keep b/test/fixtures/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/helpers/.keep b/test/helpers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/system/.keep b/test/system/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 000000000..2b5172a7d --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,24 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path("../../config/environment", __FILE__) +require "rails/test_help" +require "minitest/rails"require "minitest/reporters" # for Colorized output +# For colorful output! +Minitest::Reporters.use!( + Minitest::Reporters::SpecReporter.new, + ENV, + Minitest.backtrace_filter +) + + +# To add Capybara feature tests add `gem "minitest-rails-capybara"` +# to the test group in the Gemfile and uncomment the following: +# require "minitest/rails/capybara" + +# Uncomment for awesome colorful output +# require "minitest/pride" + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + # Add more helper methods to be used by all tests here... +end diff --git a/tmp/.keep b/tmp/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/.keep b/vendor/.keep new file mode 100644 index 000000000..e69de29bb From 66e887cbb72af68c51a2a6036339e8eb88087cea Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 18:52:39 -0700 Subject: [PATCH 02/17] Got token and made .env file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 18b43c9cd..be342dfab 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ # Ignore master key for decrypting credentials and more. /config/master.key +.env From b924815bd1a6f334f69401fe759e9d3dcbdf7018 Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 18:52:50 -0700 Subject: [PATCH 03/17] Added gems --- Gemfile | 3 +++ Gemfile.lock | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/Gemfile b/Gemfile index 6219256bd..42ed0d367 100644 --- a/Gemfile +++ b/Gemfile @@ -33,12 +33,15 @@ gem 'jbuilder', '~> 2.5' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +gem 'httparty' + # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] + gem 'dotenv-rails' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 81ff1b0a8..d4bd68293 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,6 +82,10 @@ GEM concurrent-ruby (1.0.5) crass (1.0.4) debug_inspector (0.0.3) + dotenv (2.5.0) + dotenv-rails (2.5.0) + dotenv (= 2.5.0) + railties (>= 3.2, < 6.0) erubi (1.7.1) execjs (2.7.0) ffi (1.9.25) @@ -101,6 +105,8 @@ GEM guard-minitest (2.4.6) guard-compat (~> 1.2) minitest (>= 3.0) + httparty (0.16.2) + multi_xml (>= 0.5.2) i18n (1.1.1) concurrent-ruby (~> 1.0) io-like (0.3.0) @@ -141,6 +147,7 @@ GEM ruby-progressbar msgpack (1.2.4) multi_json (1.13.1) + multi_xml (0.6.0) nenv (0.3.0) nio4r (2.3.1) nokogiri (1.8.5) @@ -251,8 +258,10 @@ DEPENDENCIES byebug capybara (>= 2.15) chromedriver-helper + dotenv-rails guard guard-minitest + httparty jbuilder (~> 2.5) jquery-rails jquery-turbolinks From 11967bf8760bbb46f8185a9ba4d7a6df1cb4b07d Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 18:53:13 -0700 Subject: [PATCH 04/17] Made recipes controller --- app/controllers/recipes_controller.rb | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 app/controllers/recipes_controller.rb diff --git a/app/controllers/recipes_controller.rb b/app/controllers/recipes_controller.rb new file mode 100644 index 000000000..87acd5eea --- /dev/null +++ b/app/controllers/recipes_controller.rb @@ -0,0 +1,28 @@ +class RecipesController < ApplicationController + + def home; end + + def index + @query = params[:query] + + if @query == "" || @query == nil + flash[:status] = :failure + flash[:message] = "Please enter the name of a recipe." + redirect_back(fallback_location: root_path) + else + @recipes = EdamamWrapper.search_recipes(@query) + #@recipes = recipes.paginate(page: params[:page], per_page: 12) + end + end + + def show + id = params[:id] + begin + @recipe = EdamamWrapper.get_recipe(id) + rescue StandardError + flash[:status] = :failure + flash[:message] = "Unable to retrieve your recipe." + redirect_to root_path + end + end +end From 79284a3a07178ac41fa53a51125fd789da735736 Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 18:53:34 -0700 Subject: [PATCH 05/17] Wrappers made --- lib/edamam_wrapper.rb | 41 +++++++++++++++++++++++++++++++++++++++++ lib/recipe.rb | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 lib/edamam_wrapper.rb create mode 100644 lib/recipe.rb diff --git a/lib/edamam_wrapper.rb b/lib/edamam_wrapper.rb new file mode 100644 index 000000000..fbd854ba2 --- /dev/null +++ b/lib/edamam_wrapper.rb @@ -0,0 +1,41 @@ +require 'httparty' + +class EdamamWrapper + class EdamamError < StandardError; end + + BASE_URL = "https://api.edamam.com/search" + ID = ENV["MUNCHER_ID"] + KEY = ENV["MUNCHER_KEYS"] + + def self.search_recipes(query) + url = BASE_URL + "?q=#{query}" + "&app_id=#{ID}" + "&app_key=#{KEY}" + "&from=0" + "&to=50" + response = HTTParty.get(url) + raise_on_error(response) + + return response["hits"].map do |recipe_hash| + Recipe.from_api(recipe_hash["recipe"]) + end + end + + def self.get_recipe(id) + uri = "http://www.edamam.com/ontologies/edamam.owl#recipe_" + "#{id}" + + encoded_uri = URI.encode(uri) + + url = BASE_URL + "?r=#{encoded_uri}" + "&app_id=#{ID}" + "&app_key=#{KEY}" + + response = HTTParty.get(url) + + raise_on_error(response) + + Recipe.from_api(response[0]) + end + + + private + def self.raise_on_error(response) + if response.code != 200 || response.body == "[]" + raise EdamamError.new("Unable to process your search at this time.") + end + end +end diff --git a/lib/recipe.rb b/lib/recipe.rb new file mode 100644 index 000000000..cc8a3f0f5 --- /dev/null +++ b/lib/recipe.rb @@ -0,0 +1,39 @@ +class Recipe + attr_reader :name, :uri, :image, :ingredients, :calories, :link, :source, :nutrients + + def initialize(name, uri, link, source, options = {}) + + if [name, uri, link, source].any? { |param| param.nil? || param.empty? } + raise ArgumentError.new("Could not create a recipe") + end + + @name = name + @uri = uri + @link = link + @source = source + @image = options[:image] + @ingredients = options[:ingredients] + @calories = options[:calories] + @nutrients = options[:nutrients] + # @nutrients = nutrients + end + + def self.from_api(recipe_hash) + if recipe_hash + self.new(recipe_hash["label"], + recipe_hash["uri"], + recipe_hash["url"], + recipe_hash["source"], + options = { + image: recipe_hash["image"], + ingredients: recipe_hash["ingredientLines"], + calories:recipe_hash["calories"], + nutrients: recipe_hash["totalNutrients"]} + ) + end + end + + def id + return self.uri[-32..-1] + end + end From 35e67e9d5a5dd240bd0982eaf48f35f1d38b71f8 Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 18:53:51 -0700 Subject: [PATCH 06/17] Routes created --- config/routes.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/routes.rb b/config/routes.rb index 787824f88..ce5c946ab 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,6 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + + root 'recipes#home' + resources :recipes, only: [:index, :show] end From 40e89bdfd13736d10743ad2c39c9dd10272d3b0e Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 18:54:53 -0700 Subject: [PATCH 07/17] View pages and form created --- app/helpers/recipes_helper.rb | 2 ++ app/views/layouts/application.html.erb | 36 +++++++++++++++---- app/views/recipes/_form.html.erb | 7 ++++ app/views/recipes/home.html.erb | 6 ++++ app/views/recipes/index.html.erb | 31 +++++++++++++++++ app/views/recipes/show.html.erb | 48 ++++++++++++++++++++++++++ config/application.rb | 2 ++ 7 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 app/helpers/recipes_helper.rb create mode 100644 app/views/recipes/_form.html.erb create mode 100644 app/views/recipes/home.html.erb create mode 100644 app/views/recipes/index.html.erb create mode 100644 app/views/recipes/show.html.erb diff --git a/app/helpers/recipes_helper.rb b/app/helpers/recipes_helper.rb new file mode 100644 index 000000000..f526316e2 --- /dev/null +++ b/app/helpers/recipes_helper.rb @@ -0,0 +1,2 @@ +module RecipesHelper +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index f2e0d8faa..d403dd070 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,15 +1,39 @@ - + - ApiMuncher - <%= csrf_meta_tags %> - <%= csp_meta_tag %> + + + + <%= content_for?(:title) ? yield(:title) : "Muncher" %> - <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> - <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> + <%= stylesheet_link_tag "application" %> + <%= javascript_include_tag "application", 'data-turbolinks-track' => true %> + <%= favicon_link_tag(source='fav.jpeg', options={}) %> + <%= csrf_meta_tags %> +
+ <%= link_to root_path do %> +

Muncher +

+ <% end %> +
Powered by <%= link_to "Edamam", "https://www.edamam.com/" %>
+
+ + +
+ <% if flash[:status].present? %> +

<%= flash[:message] %>

+ <% end %> +
<%= yield %> +
+ +
+ diff --git a/app/views/recipes/_form.html.erb b/app/views/recipes/_form.html.erb new file mode 100644 index 000000000..a08354adb --- /dev/null +++ b/app/views/recipes/_form.html.erb @@ -0,0 +1,7 @@ +
+ <%= form_tag({controller: 'recipes', action: 'index'}, method: 'get') do %> + <%= text_field_tag(:query) %> + <%= submit_tag("Search!", class: "btn btn-primary")%> + <% end %> +
+
diff --git a/app/views/recipes/home.html.erb b/app/views/recipes/home.html.erb new file mode 100644 index 000000000..38a67e6b5 --- /dev/null +++ b/app/views/recipes/home.html.erb @@ -0,0 +1,6 @@ +
+ <%= render partial: "form" %> +
+ +
diff --git a/app/views/recipes/index.html.erb b/app/views/recipes/index.html.erb new file mode 100644 index 000000000..a216d5a5a --- /dev/null +++ b/app/views/recipes/index.html.erb @@ -0,0 +1,31 @@ +
+
+
+ <%= render partial: "form" %> +
+ <% if @recipes %> +

<%= @recipes.count %> RESULTS FOR: "<%= @query.capitalize %>"

+ <% end %> +
+ +
+ <% if @recipes%> +
+ <% @recipes.each do |recipe| %> +
+ <%= link_to recipe_path(recipe.id) do %> + <%= image_tag(recipe.image, target: :_blank, alt: "#{recipe.name}") %> +
+
+ <% end %> +
+ <%= link_to "#{recipe.name}",recipe_path(recipe.id) %> +
+
+ <% end %> +
+
+ <% end %> + + diff --git a/app/views/recipes/show.html.erb b/app/views/recipes/show.html.erb new file mode 100644 index 000000000..49c7ddea4 --- /dev/null +++ b/app/views/recipes/show.html.erb @@ -0,0 +1,48 @@ +
+ <%= image_tag(@recipe.image, alt:"#{@recipe.name}") %> +
+ +
+
+

<%= @recipe.name %>

+
Recipe by: <%= link_to @recipe.source, @recipe.link, target:"_blank" %>
+
+
+ +
+
+

Ingredients

+
+ +
+
    + <% @recipe.ingredients.each do |line| %> +
    + <%= line %> +
    + <% end %> +
+
+

+
+ +
+
+
+

Nutrition Facts

+
+
+
    + <% @recipe.nutrients.each do |nutrient, value| %> +
    + <% if ["FASAT", "FAMS","FAPU", "FATRN"].include?(nutrient) %> + <%= value["label"] %> Fat: <%= value["quantity"].to_i %> <%= value["unit"] %> + <% else %> + <%= value["label"] %>: <%= value["quantity"].to_i %> <%= value["unit"] %> +
    + <% end %> + <% end %> +
+
+
+
diff --git a/config/application.rb b/config/application.rb index 0b5eed283..97c1c2a56 100644 --- a/config/application.rb +++ b/config/application.rb @@ -21,5 +21,7 @@ class Application < Rails::Application # Application configuration can go into files in config/initializers # -- all .rb files in that directory are automatically loaded after loading # the framework and any gems in your application. + + config.autoload_paths += ['lib'] end end From c6181b7abdc317961b58affc731f924e607a7e78 Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 18:58:41 -0700 Subject: [PATCH 08/17] Some styling done, in process --- app/assets/stylesheets/application.scss | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 8b1701e58..e62237c78 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -16,3 +16,50 @@ @import "bootstrap"; /* Import scss content */ @import "**/*"; + +body { + font-family: 'Apple Chancery', cursive; + text-align: center; +} + +body { + padding: 10px; + margin: 2px; +} + +.top {background-color: #CCFFFF; + padding: 20px;} + +.recipe_display { + display: grid; + grid-template: auto auto / 1fr 1fr 1fr; + justify-items: center; +} + +.recipe {padding: 2em} + +img { + border-radius: 2rem; + border-color: black; + border-style: solid; +} + +em {color: black; + font-size: 1.5em; +} +em:hover {color: darkslateblue;} + +a:hover {text-decoration: none; + color: maroon;} + +.recipe-name {font-size: 1.25em;} + +h2 {color: mediumvioletred; + font-weight: bold} + +.pic { + background-image: url("https://image.shutterstock.com/z/stock-photo-fresh-salad-with-chicken-tomatoes-and-mixed-greens-arugula-mesclun-mache-on-wooden-background-390942682.jpg"); + background-repeat: no-repeat; + height: auto; + padding: 16rem 16rem; +} From 8837b864c9a54073c583f2901c4688c9eb7cedc1 Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 20:42:32 -0700 Subject: [PATCH 09/17] Added Cassette requirements --- Gemfile | 2 + Gemfile.lock | 17 +++ app/assets/images/fav.jpeg | Bin 0 -> 4578 bytes app/assets/javascripts/recipes.js | 2 + app/assets/stylesheets/recipes.scss | 3 + test/cassettes/recipes.yml | 191 ++++++++++++++++++++++++++++ test/test_helper.rb | 16 ++- 7 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 app/assets/images/fav.jpeg create mode 100644 app/assets/javascripts/recipes.js create mode 100644 app/assets/stylesheets/recipes.scss create mode 100644 test/cassettes/recipes.yml diff --git a/Gemfile b/Gemfile index 42ed0d367..7df128627 100644 --- a/Gemfile +++ b/Gemfile @@ -68,6 +68,8 @@ gem 'jquery-rails' gem 'jquery-turbolinks' gem 'bootstrap', '~> 4.1.3' group :development, :test do + gem 'minitest-vcr' + gem 'webmock' gem 'pry-rails' end diff --git a/Gemfile.lock b/Gemfile.lock index d4bd68293..ab2ee789d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,6 +80,8 @@ GEM nokogiri (~> 1.8) coderay (1.1.2) concurrent-ruby (1.0.5) + crack (0.4.3) + safe_yaml (~> 1.0.0) crass (1.0.4) debug_inspector (0.0.3) dotenv (2.5.0) @@ -105,6 +107,7 @@ GEM guard-minitest (2.4.6) guard-compat (~> 1.2) minitest (>= 3.0) + hashdiff (0.3.7) httparty (0.16.2) multi_xml (>= 0.5.2) i18n (1.1.1) @@ -136,6 +139,8 @@ GEM mimemagic (0.3.2) mini_mime (1.0.1) mini_portile2 (2.3.0) + minispec-metadata (2.0.0) + minitest minitest (5.11.3) minitest-rails (3.0.0) minitest (~> 5.8) @@ -145,6 +150,10 @@ GEM builder minitest (>= 5.0) ruby-progressbar + minitest-vcr (1.4.0) + minispec-metadata (~> 2.0) + minitest (>= 4.7.5) + vcr (>= 2.9) msgpack (1.2.4) multi_json (1.13.1) multi_xml (0.6.0) @@ -199,6 +208,7 @@ GEM ruby-progressbar (1.10.0) ruby_dep (1.5.0) rubyzip (1.2.2) + safe_yaml (1.0.4) sass (3.6.0) sass-listen (~> 4.0.0) sass-listen (4.0.0) @@ -236,11 +246,16 @@ GEM thread_safe (~> 0.1) uglifier (4.1.19) execjs (>= 0.3.0, < 3) + vcr (4.0.0) web-console (3.7.0) actionview (>= 5.0) activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) + webmock (3.4.2) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) @@ -268,6 +283,7 @@ DEPENDENCIES listen (>= 3.0.5, < 3.2) minitest-rails minitest-reporters + minitest-vcr pg (>= 0.18, < 2.0) pry-rails puma (~> 3.11) @@ -280,6 +296,7 @@ DEPENDENCIES tzinfo-data uglifier (>= 1.3.0) web-console (>= 3.3.0) + webmock RUBY VERSION ruby 2.5.1p57 diff --git a/app/assets/images/fav.jpeg b/app/assets/images/fav.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..30dcbd3384c6e2406a79d147a3738d819e24cffd GIT binary patch literal 4578 zcmb6+cRbYp|L^1Mb)0oZ&Y?3xoDms!_V@^Al)cK9vq~t=CfQU*E)wSx$+%SVAw*?n znskA@@Ij`|SWXGw>F8OAkQ-blebnZpeNYAVMRPj-E#A zuMfh+Ob2CTpa)NlVE}{<3Z;iKFf%bh>A@Sc%TR75262xNCLSE4^}UyHWjwKhnHMFY zXB(O);29R5kaH8GQr^+|Wi_{rzZKq(tmj+VEECv2mc4ox5xL;;TUD!hd@sy ze}zT2yQvf5o`=~WS6Zcquk8a}uAbiv{Ml1n=g=e@Y+*0*);hC=s;m>faFn$C+idpD z9wJcGoqou1*lbOoFDxs}-%*_~Ui$py2bOcj&0-oK17F-&$q-x{VpyDz)J(W!lKEq{ z(Yuo2Ew#m11rZlvn`pJ_@Atj@Kh+Jk^%k3uI62k8416I zv$M7pF*dR+tN-euw?r;1BY5G3?>Eh-K(2G%|?2of3?fcd-n6@OtNWHG*Q(;Q$WUjkU$xfpzbuyX6{BjzjGC zX4x;t^yltGR&K7EuMjWhZbRE}D$GJq3hux{!Q7}!682L(ssT>E#qsj!gtfy5!H24?rpr4KUFE$G5B#)+fXDr;|VBdM48U`#(6!VzuB`Vqk_P?@( zW(PJkwQ~DfiFb;%wEwy0(r?CCsd}LQ1iF}8B$eOZuF4o|LXF_B3bOoy_l#pzcXo@4 zE*?ftKT~x1z+X21hhlyS!Ru}RGP3*pg8_H3&4R_Y6BDN1VoDo zeZm!dZg4|h?LADS2klj=fhEX{;lNDrg?-a>)Z*JTyx7qiOh0IR)q}yjA~mV0$4VM) z@Z`_3{#L3o7jt){HdnE2Z)h_blp^R)IY|8klaOJYtkSX$EhE&ta%DXiGBR;_p`21r zGE~CwaTbLrxQp&KFAODb)e^hkm+`oI3Lg@0lN7j@Rdv+s#>?@CrM?z^<-5n#iP)UN zBt?eSJ6?WnO$%ZU1KQ3fe6}5!UV?V4DihP6t$3a0%QP~w0~Um(JO|#rY^XQJ^fgHb zA%-*tQ`g>20R+h{4*sx}Jvb-c-ql`!%nEmK1WXS#UeRnBEj4w+u&w-#NF5k#P3cZQ z)$4Ohnmzex=>3fnM^o)l(T(*eC_$;Kyyt1K-TndJMulvRUPYq`c|`N$(n=TemSnXyB;=wZK|qp#OJ?oSQL)mp_w zEbj2V*0`grlm?`zj;?2y+HlM`juXfgNxzStZkLSvC zSNC)!H8{Uj?vtd6{~m@i#Qq;Wqt{jR>w~kJn=j(t~3}u z`LwxmAgn}aX!yEhNu1~hxBATEgZe&4E;w9Bf&3tak&Z3TK%gtY@CBX85T020cW&1S zs{m_8L3wXu)S9WHTALjofP6Mx`Rd=-Ie{{F1<6^4%S$6x!wb9P6RMMN8JNl6m@yc?gU)3D5CO%DDdfW}Z zneN6`R2R4A!Z5uq=DyeH_p-TxdZTNzfl=m&#FO8pFL>%n3MeD_ZfYA_MJ@UR7k9vn z@zb`DL@)!vL9geat2pwI9GHB@x^Phgl}?(C&L5Js#8%Q`;=f`6&FYlFxDu&@JQs^7 z3z+FB&d)DIB{CT+m8(}rCxrTKI(?Qz_LTU~N?$*0WcPL`p{-5A!oXN%RNrs8-OzLy zyNKyxliwqvmwv2SzT37U@Wg)3jTL*Iz=L`bG$XkW{3*GonN`%34%vPfCA}w^pH?XBb&)4yDV0_-(d5AXF?#Y}xxW(c_YkZ- zzG>Hg45T1fMI4B{&8r$r67+-WGUwcL3WQGP28$fc@(%r@-lsI;l6AIer&Q^*&hr%y z!+l`LaV6n&3hg*-4Y7dhVMn#ynJ=>%)EpnhH5g|K;&kpT%wYynz}XHa|3`w>2PbRB zXOA)kjT<#ACk_sb8;|M6fe*TH4L;z$(E!&BW}vK!9d%ue2GemORqeNsPGP*s)IQWTcVaOMeoS(%vx2uMDVEqe``4-sBtO!R3Vx=(Ij4|LE%bcLZ;5D5n??F5j?URU?y=D@o2i5mH|6TVGhj++u6rY`fkJVj zTghbG%t|n~$6*G`$1;^>VpY0t`%da-Uev;r>NM_HwAJe>EX!B5y^%w#zH5xt?Ck1O z8Z8rz58_Ct4Wy0rsssFD|xP(Ww1|-(~~z5R)t_ z-;Rj~%<{51F8OV}0#uU>PKH}_FPRA_QbG=|{Wf$6IXWPf+1zfa3x0TgvC&3puOD}lvpEAA(|SIIx)pib1X6c6t|~ddXIh@NB3R7 z7DCIbaM5rBtbqaap990@BT?!^OX3{DH$vp;-HWo~PYyjAcrral9E*vxnp#k;^$SY_ z0JbzV5)hCI;$k_@dX(zwdqqqm1CkM{75_1jc~LVb>KsvI%K?RP#ALT3@3=OW)BDyDtz)P-2cf zb``L=M|oC$oM{4G(L>dFSHKo(anSDgN&21$DCtq{3v+gyZ{dGX$C!9bq=Tt^h7y)m zqLh%@Jp48kTU=G^ZAc;onnl!eJx+FK4M`pxWVI3iUsf%|?yauh5O_Zh(}D*116 z0E4mIW=`H^AqjE4aX5PNd~8 z0mb?89_DS)NuEoa;Z)2ERWsiqoq zr*&2*Bw3s8fOD{PIp9zJ`a^#kuqfv+`}(74WiD~$(O%TkWPPs^30wUbB!lx?IO%zl zhLAVwx(G+znz*;pX(CC&VB0 zEt>oL?XB^P+Wt-Z3?w6`5X9;8o- z-XcFOj34wNZ2oriWIVM1yKH4=4GTeUgFVQcE#37E9F1Y{46B(B$6xKEI@&LpeVmO4 zD_@CXh0=(TGbf_OKjBi2hjbhZx$$ixnhNR4UF52cH|_hb&RQ7pT}9$i{t=DLP5VnG zIT#rs4xQm(6-<-SSk;vMyF)V-MKWgePOp?c<8Db)76jhz!7*;;DKD-HKe(d&8QuC2 z;V1WE@QXTYZ1r}prkdQLKUbT|mJ^(EeA4OwT-DgDlGC?JD!ilL1szjXHUjtA2ePv^ zU>*hzwPonV(hxO{N|D%67qVO4uF{X&Qm{RQcVqW^Mpnan4I-?aLjK=Ia>A9w?^W#; zp8S5-B8l*dDbBx7hwVzhsn)NI52N(3Tgb5$VW7B}0JcZI^G&~tw=`Wsf3MvtD2(Q7 zUl33`jQS#+v)!sb)?<=mq+cywu#58%Boqw^jVG&w11gXyz

+cr0E5Js@Vg*h^O z102D_CRPAw_@TnO$TJRhgAbkXwP4F5L&ky1@ct$1>OtlFx-*ImY@j|2>|h46 :new_episodes, # record new data when we don't have it yet + :match_requests_on => [:method, :uri, :body] # The http method, URI and body of a request all need to match + } + # Don't leave our APP_ID or APP_KEY lying around in a cassette file. + config.filter_sensitive_data("") { ENV["APP_ID"] } + config.filter_sensitive_data("") { ENV["APP_KEY"] } +end # To add Capybara feature tests add `gem "minitest-rails-capybara"` From fb2598405857c6b9fec66ffe5888786ec68ccdbc Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 20:42:53 -0700 Subject: [PATCH 10/17] Tests passing --- test/controllers/recipes_controller_test.rb | 66 +++++++++++++++++ test/lib/edamam_wrapper_test.rb | 82 +++++++++++++++++++++ test/lib/recipe_test.rb | 82 +++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 test/controllers/recipes_controller_test.rb create mode 100644 test/lib/edamam_wrapper_test.rb create mode 100644 test/lib/recipe_test.rb diff --git a/test/controllers/recipes_controller_test.rb b/test/controllers/recipes_controller_test.rb new file mode 100644 index 000000000..8512e03f5 --- /dev/null +++ b/test/controllers/recipes_controller_test.rb @@ -0,0 +1,66 @@ +require "test_helper" + +describe RecipesController do + describe 'home' do + it "succeeds" do + get root_path + + must_respond_with :success + end + end + + describe 'index' do + it "succeeds" do + VCR.use_cassette('recipes') do + + get recipes_path, params: {query: "brains"} + + must_respond_with :success + end + end + + it "succeeds with illogical input" do + VCR.use_cassette('recipes') do + + get recipes_path, params: {query: "qwerty"} + + must_respond_with :success + end + end + + it "flashes message with no query" do + VCR.use_cassette('recipes') do + + get recipes_path, params: {query: ""} + + must_respond_with :found + flash[:status].must_equal :failure + flash[:message].must_equal "Please enter the name of a recipe." + end + end + end + + describe 'show' do + it "succeeds" do + VCR.use_cassette('recipes') do + recipes = EdamamWrapper.search_recipes("brains") + recipe = recipes.first + + get recipe_path(recipe.id) + must_respond_with :success + end + end + + it "fails with invalid recipe id" do + VCR.use_cassette('recipes') do + + get recipe_path("0000") + + flash[:status].must_equal :failure + flash[:message].must_equal "Unable to retrieve your recipe." + must_respond_with :redirect + end + end + end + +end diff --git a/test/lib/edamam_wrapper_test.rb b/test/lib/edamam_wrapper_test.rb new file mode 100644 index 000000000..0b3790326 --- /dev/null +++ b/test/lib/edamam_wrapper_test.rb @@ -0,0 +1,82 @@ +require 'test_helper' + +describe Recipe do + before do + data = { + "uri": "http://www.edamam.com/ontologies/edamam.owl#recipe_3c5cf4968fa095cbdd9fca6ab5389e9c", + "label": "Pickled Brains recipes", + "image": "https://www.edamam.com/web-img/811/811a71bad21d73adb7fc6e92801f8ec4", + "source": "Martha Stewart", + "url": "http://www.marthastewart.com/318853/pickled-brains", + "ingredientLines": [ + "1 cup red-wine vinegar", + "3 cups white-wine vinegar", + "1 cup sugar", + "1/2 cup salt", + "1 tablespoon black peppercorns", + "1 tablespoon brown mustard seeds", + "5 or 6 red pearl onions", + "2 to 3 heads cauliflower" + ], + "calories": 1366.364111111111, + "totalNutrients": { + "ENERC_KCAL": { + "label": "Energy", + "quantity": 948.5783323955536, + "unit": "kcal" + }, + "FAT": { + "label": "Fat", + "quantity": 66.042283310318, + "unit": "g" + } + } + } + + @recipe = Recipe.new(data[:label], + data[:uri], + data[:url], + data[:source], + options = { + image: data[:image], + ingredients: data[:ingredientLines], + calories:data[:calories]} + ) + end + describe "initialize" do + it "can be created with valid data" do + @recipe.must_be_kind_of Recipe + @recipe.name.must_equal "Pickled Brains recipes" + @recipe.uri.must_equal "http://www.edamam.com/ontologies/edamam.owl#recipe_3c5cf4968fa095cbdd9fca6ab5389e9c" + @recipe.image.must_equal "https://www.edamam.com/web-img/811/811a71bad21d73adb7fc6e92801f8ec4" + @recipe.ingredients.must_equal [ + "1 cup red-wine vinegar", + "3 cups white-wine vinegar", + "1 cup sugar", + "1/2 cup salt", + "1 tablespoon black peppercorns", + "1 tablespoon brown mustard seeds", + "5 or 6 red pearl onions", + "2 to 3 heads cauliflower" + ] + @recipe.calories.must_equal 1366.364111111111 + @recipe.link.must_equal "http://www.marthastewart.com/318853/pickled-brains" + @recipe.source.must_equal "Martha Stewart" + end + + it "raises error if data is incomplete" do + proc { Recipe.new() }.must_raise ArgumentError + proc { Recipe.new("uri", "label") }.must_raise ArgumentError + proc { Recipe.new("", "", "", "") }.must_raise ArgumentError + end + + it "raises error if required data contain nil" do + proc { Recipe.new("name", nil, "image", "ingredients", "calories", "link", "source") }.must_raise ArgumentError + end + end + describe "id" do + it "must return the id of a uri" do + @recipe.id.must_equal "3c5cf4968fa095cbdd9fca6ab5389e9c" + end + end +end diff --git a/test/lib/recipe_test.rb b/test/lib/recipe_test.rb new file mode 100644 index 000000000..0b3790326 --- /dev/null +++ b/test/lib/recipe_test.rb @@ -0,0 +1,82 @@ +require 'test_helper' + +describe Recipe do + before do + data = { + "uri": "http://www.edamam.com/ontologies/edamam.owl#recipe_3c5cf4968fa095cbdd9fca6ab5389e9c", + "label": "Pickled Brains recipes", + "image": "https://www.edamam.com/web-img/811/811a71bad21d73adb7fc6e92801f8ec4", + "source": "Martha Stewart", + "url": "http://www.marthastewart.com/318853/pickled-brains", + "ingredientLines": [ + "1 cup red-wine vinegar", + "3 cups white-wine vinegar", + "1 cup sugar", + "1/2 cup salt", + "1 tablespoon black peppercorns", + "1 tablespoon brown mustard seeds", + "5 or 6 red pearl onions", + "2 to 3 heads cauliflower" + ], + "calories": 1366.364111111111, + "totalNutrients": { + "ENERC_KCAL": { + "label": "Energy", + "quantity": 948.5783323955536, + "unit": "kcal" + }, + "FAT": { + "label": "Fat", + "quantity": 66.042283310318, + "unit": "g" + } + } + } + + @recipe = Recipe.new(data[:label], + data[:uri], + data[:url], + data[:source], + options = { + image: data[:image], + ingredients: data[:ingredientLines], + calories:data[:calories]} + ) + end + describe "initialize" do + it "can be created with valid data" do + @recipe.must_be_kind_of Recipe + @recipe.name.must_equal "Pickled Brains recipes" + @recipe.uri.must_equal "http://www.edamam.com/ontologies/edamam.owl#recipe_3c5cf4968fa095cbdd9fca6ab5389e9c" + @recipe.image.must_equal "https://www.edamam.com/web-img/811/811a71bad21d73adb7fc6e92801f8ec4" + @recipe.ingredients.must_equal [ + "1 cup red-wine vinegar", + "3 cups white-wine vinegar", + "1 cup sugar", + "1/2 cup salt", + "1 tablespoon black peppercorns", + "1 tablespoon brown mustard seeds", + "5 or 6 red pearl onions", + "2 to 3 heads cauliflower" + ] + @recipe.calories.must_equal 1366.364111111111 + @recipe.link.must_equal "http://www.marthastewart.com/318853/pickled-brains" + @recipe.source.must_equal "Martha Stewart" + end + + it "raises error if data is incomplete" do + proc { Recipe.new() }.must_raise ArgumentError + proc { Recipe.new("uri", "label") }.must_raise ArgumentError + proc { Recipe.new("", "", "", "") }.must_raise ArgumentError + end + + it "raises error if required data contain nil" do + proc { Recipe.new("name", nil, "image", "ingredients", "calories", "link", "source") }.must_raise ArgumentError + end + end + describe "id" do + it "must return the id of a uri" do + @recipe.id.must_equal "3c5cf4968fa095cbdd9fca6ab5389e9c" + end + end +end From a015d907ae058796ec17e97c85657fc921c762a0 Mon Sep 17 00:00:00 2001 From: Divya Date: Sat, 3 Nov 2018 21:10:06 -0700 Subject: [PATCH 11/17] Testung favicon removal heroku --- app/views/layouts/application.html.erb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index d403dd070..27328cf8b 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,7 +8,6 @@ <%= stylesheet_link_tag "application" %> <%= javascript_include_tag "application", 'data-turbolinks-track' => true %> - <%= favicon_link_tag(source='fav.jpeg', options={}) %> <%= csrf_meta_tags %> From 67648b73cfe08865e96da204b449fe97ccf96489 Mon Sep 17 00:00:00 2001 From: Divya Date: Tue, 6 Nov 2018 21:52:54 -0800 Subject: [PATCH 12/17] Pagination successful! --- Gemfile | 5 +- Gemfile.lock | 18 ++++ app/controllers/recipes_controller.rb | 2 +- app/views/recipes/index.html.erb | 7 ++ config/initializers/kaminari_config.rb | 12 +++ .../initializers/will_paginate_array_fix.rb | 1 + test/lib/edamam_wrapper_test.rb | 96 +++++-------------- 7 files changed, 67 insertions(+), 74 deletions(-) create mode 100644 config/initializers/kaminari_config.rb create mode 100644 config/initializers/will_paginate_array_fix.rb diff --git a/Gemfile b/Gemfile index 7df128627..2c703f8d7 100644 --- a/Gemfile +++ b/Gemfile @@ -32,9 +32,9 @@ gem 'jbuilder', '~> 2.5' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development - +gem 'will_paginate', '~> 3.1.6' gem 'httparty' - +gem 'kaminari' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false @@ -78,6 +78,7 @@ group :development do gem 'binding_of_caller' gem 'guard' gem 'guard-minitest' + gem 'kaminari' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index ab2ee789d..1bd2fcf42 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -123,6 +123,18 @@ GEM jquery-turbolinks (2.1.0) railties (>= 3.1.0) turbolinks + kaminari (1.1.1) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.1.1) + kaminari-activerecord (= 1.1.1) + kaminari-core (= 1.1.1) + kaminari-actionview (1.1.1) + actionview + kaminari-core (= 1.1.1) + kaminari-activerecord (1.1.1) + activerecord + kaminari-core (= 1.1.1) + kaminari-core (1.1.1) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -259,6 +271,9 @@ GEM websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) + will_paginate (3.1.6) + will_paginate-bootstrap (1.0.1) + will_paginate (>= 3.0.3) xpath (3.2.0) nokogiri (~> 1.8) @@ -280,6 +295,7 @@ DEPENDENCIES jbuilder (~> 2.5) jquery-rails jquery-turbolinks + kaminari listen (>= 3.0.5, < 3.2) minitest-rails minitest-reporters @@ -297,6 +313,8 @@ DEPENDENCIES uglifier (>= 1.3.0) web-console (>= 3.3.0) webmock + will_paginate (~> 3.1.6) + will_paginate-bootstrap RUBY VERSION ruby 2.5.1p57 diff --git a/app/controllers/recipes_controller.rb b/app/controllers/recipes_controller.rb index 87acd5eea..1b324d496 100644 --- a/app/controllers/recipes_controller.rb +++ b/app/controllers/recipes_controller.rb @@ -10,7 +10,7 @@ def index flash[:message] = "Please enter the name of a recipe." redirect_back(fallback_location: root_path) else - @recipes = EdamamWrapper.search_recipes(@query) + @recipes = EdamamWrapper.search_recipes(@query).paginate(page: params[:page], per_page: 10) #@recipes = recipes.paginate(page: params[:page], per_page: 12) end end diff --git a/app/views/recipes/index.html.erb b/app/views/recipes/index.html.erb index a216d5a5a..564753cd9 100644 --- a/app/views/recipes/index.html.erb +++ b/app/views/recipes/index.html.erb @@ -25,7 +25,14 @@

<% end %> +
+ <%= page_entries_info @recipes %> + <%= will_paginate @recipes, container: false %> +
+ + <% end %> + diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb new file mode 100644 index 000000000..b02c76fca --- /dev/null +++ b/config/initializers/kaminari_config.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +Kaminari.configure do |config| + config.default_per_page = 5 + # config.max_per_page = nil + # config.window = 4 + # config.outer_window = 0 + # config.left = 0 + # config.right = 0 + # config.page_method_name = :page + # config.param_name = :page + # config.params_on_first_page = false +end diff --git a/config/initializers/will_paginate_array_fix.rb b/config/initializers/will_paginate_array_fix.rb new file mode 100644 index 000000000..dfed3fe9e --- /dev/null +++ b/config/initializers/will_paginate_array_fix.rb @@ -0,0 +1 @@ +require 'will_paginate/array' diff --git a/test/lib/edamam_wrapper_test.rb b/test/lib/edamam_wrapper_test.rb index 0b3790326..218fe1a43 100644 --- a/test/lib/edamam_wrapper_test.rb +++ b/test/lib/edamam_wrapper_test.rb @@ -1,82 +1,36 @@ require 'test_helper' -describe Recipe do - before do - data = { - "uri": "http://www.edamam.com/ontologies/edamam.owl#recipe_3c5cf4968fa095cbdd9fca6ab5389e9c", - "label": "Pickled Brains recipes", - "image": "https://www.edamam.com/web-img/811/811a71bad21d73adb7fc6e92801f8ec4", - "source": "Martha Stewart", - "url": "http://www.marthastewart.com/318853/pickled-brains", - "ingredientLines": [ - "1 cup red-wine vinegar", - "3 cups white-wine vinegar", - "1 cup sugar", - "1/2 cup salt", - "1 tablespoon black peppercorns", - "1 tablespoon brown mustard seeds", - "5 or 6 red pearl onions", - "2 to 3 heads cauliflower" - ], - "calories": 1366.364111111111, - "totalNutrients": { - "ENERC_KCAL": { - "label": "Energy", - "quantity": 948.5783323955536, - "unit": "kcal" - }, - "FAT": { - "label": "Fat", - "quantity": 66.042283310318, - "unit": "g" - } - } - } +describe EdamamWrapper do + describe 'search_recipes' do + it "gives a list of recipes" do + VCR.use_cassette('recipes') do + recipes = EdamamWrapper.search_recipes("brains") - @recipe = Recipe.new(data[:label], - data[:uri], - data[:url], - data[:source], - options = { - image: data[:image], - ingredients: data[:ingredientLines], - calories:data[:calories]} - ) - end - describe "initialize" do - it "can be created with valid data" do - @recipe.must_be_kind_of Recipe - @recipe.name.must_equal "Pickled Brains recipes" - @recipe.uri.must_equal "http://www.edamam.com/ontologies/edamam.owl#recipe_3c5cf4968fa095cbdd9fca6ab5389e9c" - @recipe.image.must_equal "https://www.edamam.com/web-img/811/811a71bad21d73adb7fc6e92801f8ec4" - @recipe.ingredients.must_equal [ - "1 cup red-wine vinegar", - "3 cups white-wine vinegar", - "1 cup sugar", - "1/2 cup salt", - "1 tablespoon black peppercorns", - "1 tablespoon brown mustard seeds", - "5 or 6 red pearl onions", - "2 to 3 heads cauliflower" - ] - @recipe.calories.must_equal 1366.364111111111 - @recipe.link.must_equal "http://www.marthastewart.com/318853/pickled-brains" - @recipe.source.must_equal "Martha Stewart" + recipes.each do |recipe| + recipe.must_be_kind_of Recipe + end end + end + end - it "raises error if data is incomplete" do - proc { Recipe.new() }.must_raise ArgumentError - proc { Recipe.new("uri", "label") }.must_raise ArgumentError - proc { Recipe.new("", "", "", "") }.must_raise ArgumentError - end + describe 'get_recipe' do + it "retrieves a specific recipe" do + VCR.use_cassette('recipes') do + recipes = EdamamWrapper.search_recipes("brains") + recipe = recipes.first - it "raises error if required data contain nil" do - proc { Recipe.new("name", nil, "image", "ingredients", "calories", "link", "source") }.must_raise ArgumentError + first_recipe = EdamamWrapper.get_recipe(recipe.id) + first_recipe.must_be_kind_of Recipe + first_recipe.name.must_equal recipe.name end end - describe "id" do - it "must return the id of a uri" do - @recipe.id.must_equal "3c5cf4968fa095cbdd9fca6ab5389e9c" + + it "raises StandardError for a bad recipe id" do + VCR.use_cassette('recipes') do + proc { EdamamWrapper.get_recipe(0000) }.must_raise end + end + + end end From 1e83bda6002b24d62d2e42ff5ccf6404f6aaa998 Mon Sep 17 00:00:00 2001 From: Divya Date: Tue, 6 Nov 2018 21:58:47 -0800 Subject: [PATCH 13/17] Added gem for bootstrap pagination --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 2c703f8d7..7cb3866bf 100644 --- a/Gemfile +++ b/Gemfile @@ -33,6 +33,7 @@ gem 'jbuilder', '~> 2.5' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development gem 'will_paginate', '~> 3.1.6' +gem 'will_paginate-bootstrap' gem 'httparty' gem 'kaminari' # Reduces boot times through caching; required in config/boot.rb From 68f4ada868928b6cbacd9a8494c2e25bff6efffb Mon Sep 17 00:00:00 2001 From: Divya Date: Wed, 7 Nov 2018 14:21:33 -0800 Subject: [PATCH 14/17] Revert "Added gem for bootstrap pagination" This reverts commit 1e83bda6002b24d62d2e42ff5ccf6404f6aaa998. --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index 7cb3866bf..2c703f8d7 100644 --- a/Gemfile +++ b/Gemfile @@ -33,7 +33,6 @@ gem 'jbuilder', '~> 2.5' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development gem 'will_paginate', '~> 3.1.6' -gem 'will_paginate-bootstrap' gem 'httparty' gem 'kaminari' # Reduces boot times through caching; required in config/boot.rb From d4475722fb5311dd3d414083a10c1f7beddaddc9 Mon Sep 17 00:00:00 2001 From: Divya Date: Wed, 7 Nov 2018 14:25:23 -0800 Subject: [PATCH 15/17] Bundle install --- Gemfile.lock | 3 --- 1 file changed, 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1bd2fcf42..4f5f1c158 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -272,8 +272,6 @@ GEM websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) will_paginate (3.1.6) - will_paginate-bootstrap (1.0.1) - will_paginate (>= 3.0.3) xpath (3.2.0) nokogiri (~> 1.8) @@ -314,7 +312,6 @@ DEPENDENCIES web-console (>= 3.3.0) webmock will_paginate (~> 3.1.6) - will_paginate-bootstrap RUBY VERSION ruby 2.5.1p57 From 45a01a9dbdcdec0d8938b39e72a1987dcb4694a1 Mon Sep 17 00:00:00 2001 From: Divya Date: Wed, 7 Nov 2018 15:24:47 -0800 Subject: [PATCH 16/17] Changed API key nomenclature --- lib/edamam_wrapper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/edamam_wrapper.rb b/lib/edamam_wrapper.rb index fbd854ba2..7a6a3a3fb 100644 --- a/lib/edamam_wrapper.rb +++ b/lib/edamam_wrapper.rb @@ -4,8 +4,8 @@ class EdamamWrapper class EdamamError < StandardError; end BASE_URL = "https://api.edamam.com/search" - ID = ENV["MUNCHER_ID"] - KEY = ENV["MUNCHER_KEYS"] + ID = ENV["APP_ID"] + KEY = ENV["APP_KEYS"] def self.search_recipes(query) url = BASE_URL + "?q=#{query}" + "&app_id=#{ID}" + "&app_key=#{KEY}" + "&from=0" + "&to=50" From 4af01479fadad05db9aac8dc2ae35774fe6a0f79 Mon Sep 17 00:00:00 2001 From: Divya Date: Wed, 7 Nov 2018 15:37:39 -0800 Subject: [PATCH 17/17] MAde changes to help config --- config/application.rb | 2 +- lib/edamam_wrapper.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/application.rb b/config/application.rb index 97c1c2a56..3a0ce6e1d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -22,6 +22,6 @@ class Application < Rails::Application # -- all .rb files in that directory are automatically loaded after loading # the framework and any gems in your application. - config.autoload_paths += ['lib'] + config.autoload_paths << Rails.root.join('lib') end end diff --git a/lib/edamam_wrapper.rb b/lib/edamam_wrapper.rb index 7a6a3a3fb..fbd854ba2 100644 --- a/lib/edamam_wrapper.rb +++ b/lib/edamam_wrapper.rb @@ -4,8 +4,8 @@ class EdamamWrapper class EdamamError < StandardError; end BASE_URL = "https://api.edamam.com/search" - ID = ENV["APP_ID"] - KEY = ENV["APP_KEYS"] + ID = ENV["MUNCHER_ID"] + KEY = ENV["MUNCHER_KEYS"] def self.search_recipes(query) url = BASE_URL + "?q=#{query}" + "&app_id=#{ID}" + "&app_key=#{KEY}" + "&from=0" + "&to=50"