Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
Create initial tasks API
Browse files Browse the repository at this point in the history
  • Loading branch information
bobwhitelock committed May 20, 2021
1 parent c348f41 commit 42c7504
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
34 changes: 34 additions & 0 deletions app/controllers/api/tasks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class Api::TasksController < ApplicationController
before_action :set_default_response_format

def index
render_tasks
end

def update
type = params[:action]
arguments = params[:arguments]
Delta.create!(type: type, arguments: arguments)
render_tasks
end

private

def set_default_response_format
request.format = :json
end

def render_tasks
DeltaApplier.apply(
todo_repo: todo_repo,
deltas: Delta.pending,
commit: false
)

render json: {data: todo_repo.list.map(&:to_json)}
end

def todo_repo
@_todo_repo ||= TodoRepo.new(Figaro.env.TODO_FILE!)
end
end
5 changes: 5 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
post :unschedule
end

namespace :api do
get "/tasks" => "tasks#index"
post "/tasks" => "tasks#update"
end

# Any other non-XHR, HTML request should render the React client.
get "*path", to: "application#client_index_html", constraints: lambda { |request|
!request.xhr? && request.format.html?
Expand Down
70 changes: 70 additions & 0 deletions spec/requests/api/tasks_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require "base64"

require "rails_helper"
require "support/repo_utils"

RSpec.describe "/api/tasks" do
include RepoUtils

let(:test_username) { "user" }
let(:test_password) { "password" }

def mock_auth_config
allow(Figaro.env).to receive("AUTH_USER!").and_return(test_username)
allow(Figaro.env).to receive("AUTH_PASSWORD!").and_return(test_password)
end

def basic_auth_header
{Authorization: "Basic #{Base64.encode64("#{test_username}:#{test_password}")}"}
end

describe "GET /api/tasks" do
# XXX Should do anything to the tasks? or leave this to the frontend?
it "returns all tasks in the repo" do
mock_auth_config
mock_todo_repo("a task", "another task", "x a complete task")

get "/api/tasks", headers: basic_auth_header

expect(response.status).to eq(200)
response_json = JSON.parse(response.body).deep_symbolize_keys
raw_tasks = response_json[:data].map { |t| t[:raw] }
expect(raw_tasks).to eq(["a task", "another task", "x a complete task"])
end

it "includes changes from unapplied deltas" do
mock_auth_config
mock_todo_repo("a task")
create(:delta, type: :add, arguments: ["another task"])
now = Time.local(2021, 2, 9)
Timecop.freeze(now)

get "/api/tasks", headers: basic_auth_header

expect(response.status).to eq(200)
response_json = JSON.parse(response.body).deep_symbolize_keys
raw_tasks = response_json[:data].map { |t| t[:raw] }
expect(raw_tasks).to eq(["a task", "2021-02-09 another task"])
end
end

# XXX Also test POST with invalid task? Should return 422?
describe "POST /api/tasks" do
it "creates a delta for the given change and returns the new tasks" do
mock_auth_config
mock_todo_repo("a task")

post_data = {
action: Delta::UPDATE,
arguments: ["a task", "updated task"]
}
post "/api/tasks", headers: basic_auth_header, params: post_data

# XXX DRY this up?
expect(response.status).to eq(200)
response_json = JSON.parse(response.body).deep_symbolize_keys
raw_tasks = response_json[:data].map { |t| t[:raw] }
expect(raw_tasks).to eq(["updated task"])
end
end
end
1 change: 1 addition & 0 deletions spec/support/repo_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ def mock_todo_repo(*tasks)
end
temp_file.write
temp_file.rewind
allow(Figaro.env).to receive("TODO_FILE!").and_return(temp_file)
TodoRepo.new(temp_file.path)
end

Expand Down

0 comments on commit 42c7504

Please sign in to comment.