Introduce AsciicastListPresenter

openid
Marcin Kulik 11 years ago
parent f6ad790a09
commit d571be2bbd

@ -7,10 +7,9 @@ class AsciicastsController < ApplicationController
respond_to :html, :json, :js
def index
asciicasts = AsciicastList.new(params[:category], params[:order])
render locals: {
asciicast_list: AsciicastListDecorator.new(asciicasts, params[:page])
page: AsciicastListPresenter.new(params[:category], params[:order],
params[:page])
}
end

@ -1,23 +0,0 @@
class AsciicastListDecorator < ApplicationDecorator
PER_PAGE = 12
attr_reader :page, :per_page
delegate_all
def initialize(model, page, per_page = nil)
super(model)
@page = page
@per_page = per_page || PER_PAGE
end
def category_name
"#{category.to_s.capitalize} asciicasts"
end
def items
PaginatingDecorator.new(model.items.paginate(page, per_page))
end
end

@ -36,14 +36,20 @@ class Asciicast < ActiveRecord::Base
page(page).per(per_page)
end
def self.for_category_ordered(category, order)
def self.for_category_ordered(category, order, page = nil, per_page = nil)
collection = all
if category == :featured
collection = collection.featured
end
collection.order("#{ORDER_MODES[order]} DESC")
collection = collection.order("#{ORDER_MODES[order]} DESC")
if page
collection = collection.paginate(page, per_page)
end
collection
end
def user

@ -1,15 +0,0 @@
class AsciicastList
attr_reader :category, :order, :repository
def initialize(category, order, repository = Asciicast)
@category = (category || :all).to_sym
@order = (order || :recency).to_sym
@repository = repository
end
def items
repository.for_category_ordered(category, order)
end
end

@ -0,0 +1,24 @@
class AsciicastListPresenter
PER_PAGE = 12
attr_reader :category, :order, :page, :per_page
def initialize(category, order, page, per_page = nil)
@category = (category || :all).to_sym
@order = (order || :recency).to_sym
@per_page = per_page || PER_PAGE
@page = page || 1
end
def category_name
"#{category.to_s.capitalize} asciicasts"
end
def items
PaginatingDecorator.new(
Asciicast.for_category_ordered(category, order, page, per_page)
)
end
end

@ -1,22 +1,22 @@
- content_for(:title, asciicast_list.category_name)
- content_for(:title, page.category_name)
.asciicasts-list-page
.container
.row
.col-md-3
= render 'shared/browse_categories', current_category: asciicast_list.category
= render 'shared/browse_categories', current_category: page.category
.col-md-9
.row
.col-md-6
h2 = asciicast_list.category_name
h2 = page.category_name
.col-md-6.text-right
.sorting
span Sort by
.btn-group.text-left
button.btn.btn-default.dropdown-toggle[type="button" data-toggle="dropdown"]
| #{asciicast_list.order}
| #{page.order}
span.caret
ul.dropdown-menu[role="menu"]
li
@ -28,5 +28,5 @@
.row.asciicast-list
.col-md-12
= render 'asciicasts/previews', asciicasts: asciicast_list.items, per_row: 2
= paginate asciicast_list.items
= render 'asciicasts/previews', asciicasts: page.items, per_row: 2
= paginate page.items

@ -18,25 +18,19 @@ describe AsciicastsController do
subject { response }
describe '#index' do
let(:asciicast_list) { double('asciicast_list') }
let(:decorated_asciicast_list) { double('decorated_asciicast_list') }
let(:asciicast_list_presenter) { double('asciicast_list_presenter') }
before do
allow(controller).to receive(:render)
allow(AsciicastList).to receive(:new).
with('featured', 'recency') { asciicast_list }
allow(AsciicastListDecorator).to receive(:new).
with(asciicast_list, '2') { decorated_asciicast_list }
allow(AsciicastListPresenter).to receive(:new).
with('featured', 'recency', '2') { asciicast_list_presenter }
get :index, category: 'featured', order: 'recency', page: '2'
end
it { should be_success }
it 'renders template with asciicast_list' do
it "renders template with AsciicastListPresenter as page" do
expect(controller).to have_received(:render).
with(locals: { asciicast_list: decorated_asciicast_list })
with(locals: { page: asciicast_list_presenter })
end
end

@ -1,34 +0,0 @@
require 'spec_helper'
describe AsciicastListDecorator do
let(:decorator) { described_class.new(list, 3, 10) }
let(:list) { double('list', category: :foo, items: items) }
let(:items) { double('items', paginate: paginated) }
let(:paginated) { [Asciicast.new] }
describe '#category_name' do
subject { decorator.category_name }
it { should eq('Foo asciicasts') }
end
describe '#items' do
subject { decorator.items }
it 'returns the items paginated' do
expect(subject).to eq(paginated)
expect(items).to have_received(:paginate).with(3, 10)
end
it 'wraps the paginated items in a PaginatingDecorator' do
paginating_decorator = double('paginating_decorator')
allow(PaginatingDecorator).to receive(:new).
with(paginated) { paginating_decorator }
expect(subject).to be(paginating_decorator)
end
end
end

@ -1,63 +0,0 @@
require 'spec_helper'
describe AsciicastList do
let(:list) { described_class.new(category, order, repository) }
let(:category) { 'featured' }
let(:order) { 'recency' }
let(:repository) { double('repository') }
describe '#category' do
subject { list.category }
context "when it was passed as a string" do
let(:category) { 'thecat' }
it { should eq(:thecat) }
end
context "when it was passed as nil" do
let(:category) { nil }
it { should eq(:all) }
end
end
describe '#order' do
subject { list.order }
context "when it was passed as a string" do
let(:order) { 'thecat' }
it { should eq(:thecat) }
end
context "when it was passed as nil" do
let(:order) { nil }
it { should eq(:recency) }
end
end
describe '#items' do
subject { list.items }
let(:category) { 'foo' }
let(:order) { 'bar' }
let(:asciicasts) { [Asciicast.new] }
before do
allow(repository).to receive(:for_category_ordered) { asciicasts }
subject
end
it { should eq(asciicasts) }
it 'calls for_category_ordered on repository with proper args' do
expect(repository).to have_received(:for_category_ordered).
with(:foo, :bar)
end
end
end

@ -0,0 +1,72 @@
require 'spec_helper'
describe AsciicastListPresenter do
let(:presenter) { described_class.new(category, order, page, per_page) }
let(:category) { 'awesome' }
let(:order) { 'awesomeness' }
let(:page) { 2 }
let(:per_page) { 5 }
describe '#category' do
subject { presenter.category }
let(:category) { nil }
it "defaults to :all" do
expect(subject).to eq(:all)
end
end
describe '#order' do
subject { presenter.order }
let(:order) { nil }
it "defaults to :recency" do
expect(subject).to eq(:recency)
end
end
describe '#page' do
subject { presenter.page }
let(:page) { nil }
it "defaults to 1" do
expect(subject).to eq(1)
end
end
describe '#category_name' do
subject { presenter.category_name }
it { should eq('Awesome asciicasts') }
end
describe '#items' do
subject { presenter.items }
let(:collection) { [asciicast] }
let(:asciicast) { double('asciicast', decorate: double(title: 'quux')) }
before do
allow(Asciicast).to receive(:for_category_ordered) { collection }
end
it "gets the asciicasts for given category, order, page and per_page" do
subject
expect(Asciicast).to have_received(:for_category_ordered).
with(:awesome, :awesomeness, 2, 5)
end
it "wraps the asciicasts with paginating decorator" do
expect(subject).to respond_to(:current_page)
expect(subject).to respond_to(:total_pages)
expect(subject).to respond_to(:limit_value)
expect(subject.first.title).to eq('quux')
end
end
end
Loading…
Cancel
Save