Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BE | Create PuzzlesController#index Endpoint #26

Merged
merged 11 commits into from
Oct 20, 2023
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruby 3.1.1
17 changes: 17 additions & 0 deletions app/controllers/api/v1/puzzles_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Api::V1::PuzzlesController < ApplicationController

def index

zip_code = params[:zip_code]

users = User.where(zip_code: zip_code) if zip_code.present?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic should probably be a method in the models and only called on here in the controller. But again, to meet MVP within out time limits let's just roll with it for now. Nice work.


if users != []
puzzles = Puzzle.where(user_id: users.pluck(:id))
render json: PuzzleSerializer.new(puzzles)
elsif puzzles == [] || users = []
render json: { error: "Puzzles not found in this area" }, status: "404"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error handling works for now to meet MVP within our time limitation. But in a refactor we'll want to get this working through the ErrorSerializer. : )

end
end

end
3 changes: 2 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
Rails.application.routes.draw do
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

# Defines the root path route ("/")
# root "articles#index"

namespace :api do
namespace :v1 do
# resources :users, only: [:show] #for ease of understanding, we will skip resoruces for now
put 'puzzles', to: 'puzzles#index'

get '/users/:user_id', to: 'users#show'
get '/users/:user_id/dashboard', to: 'users#dashboard'

Expand Down
84 changes: 84 additions & 0 deletions spec/requests/api/v1/puzzles_request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require 'rails_helper'

RSpec.describe "PuzzlesController", type: :request do
describe "#ndex" do
context 'when successful' do
it "returns all puzzles from a zipcode" do
zip_code = 12345

user_1 = create(:user, id: 1, zip_code: zip_code)
user_2 = create(:user, id: 2, zip_code: zip_code)
user_3 = create(:user, id: 3, zip_code: 54321)
puzzle_1 = create(:puzzle, user: user_1)
puzzle_2 = create(:puzzle, user: user_1)
puzzle_3 = create(:puzzle, user: user_2)
puzzle_4 = create(:puzzle, user: user_3)

zipcode_params = { zip_code: 12345 }

headers = { 'CONTENT_TYPE' => 'application/json' }
put "/api/v1/puzzles", headers: headers, params: JSON.generate(zipcode_params)

expect(response).to have_http_status(200)

parsed_data = JSON.parse(response.body, symbolize_names: true)

expect(parsed_data).to be_a(Hash)
expect(parsed_data.keys).to eq([:data])
expect(parsed_data[:data]).to be_an(Array)
expect(parsed_data[:data][0]).to be_a(Hash)
expect(parsed_data[:data][0].keys).to eq([:id, :type, :attributes])

expect(parsed_data[:data][0][:attributes]).to be_a(Hash)
expect(parsed_data[:data][0][:attributes].keys).to eq([:user_id, :status, :title, :description, :total_pieces, :notes, :puzzle_image_url])
expect(parsed_data[:data][0][:attributes][:user_id]).to eq(puzzle_1.user_id)
expect(parsed_data[:data][0][:attributes][:status]).to eq(puzzle_1.status)
expect(parsed_data[:data][0][:attributes][:title]).to eq(puzzle_1.title)
expect(parsed_data[:data][0][:attributes][:description]).to eq(puzzle_1.description)
expect(parsed_data[:data][0][:attributes][:total_pieces]).to eq(puzzle_1.total_pieces)
expect(parsed_data[:data][0][:attributes][:notes]).to eq(puzzle_1.notes)
expect(parsed_data[:data][0][:attributes][:puzzle_image_url]).to eq(puzzle_1.puzzle_image_url)

# NOTE Could refactor tests to not see a puzzle_4 in the test because it's in a diff zipcode
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent note here. And I agree that there should be a test to confirm no "stray" puzzles are found in a call for a specific zip_code.


expect(parsed_data[:data][2][:attributes]).to be_a(Hash)
expect(parsed_data[:data][2][:attributes].keys).to eq([:user_id, :status, :title, :description, :total_pieces, :notes, :puzzle_image_url])
expect(parsed_data[:data][2][:attributes][:user_id]).to eq(puzzle_3.user_id)
expect(parsed_data[:data][2][:attributes][:status]).to eq(puzzle_3.status)
expect(parsed_data[:data][2][:attributes][:title]).to eq(puzzle_3.title)
expect(parsed_data[:data][2][:attributes][:description]).to eq(puzzle_3.description)
expect(parsed_data[:data][2][:attributes][:total_pieces]).to eq(puzzle_3.total_pieces)
expect(parsed_data[:data][2][:attributes][:notes]).to eq(puzzle_3.notes)
expect(parsed_data[:data][2][:attributes][:puzzle_image_url]).to eq(puzzle_3.puzzle_image_url)


end
end

context 'when NOT successful' do
it 'returns an error message when zipcode is not found' do
zip_code = 12345
user_1 = create(:user, id: 1, zip_code: 54321)
user_2 = create(:user, id: 2, zip_code: 12346)
puzzle_1 = create(:puzzle, user: user_1)
puzzle_2 = create(:puzzle, user: user_1)
puzzle_3 = create(:puzzle, user: user_2)
puzzle_4 = create(:puzzle, user: user_2)

zipcode_params = { zip_code: 00000 }

headers = { 'CONTENT_TYPE' => 'application/json' }
put "/api/v1/puzzles", headers: headers, params: JSON.generate(zipcode_params)

expect(response).to have_http_status(404)

parsed_error_data = JSON.parse(response.body, symbolize_names: true)

expect(parsed_error_data).to be_a(Hash)
expect(parsed_error_data.keys).to eq([:error])
expect(parsed_error_data[:error]).to eq("Puzzles not found in this area")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And these tests would change once we use the ErrorSerializer in a refactor.

end

end
end
end