day mood for a post responds to content

extract creating a post with templates to a static post view method.

Legacy templates extracted, day view

day mood shows photos and has variable text size
This commit is contained in:
Dennis Collinson 2012-03-26 17:02:09 -07:00
parent 663abcb0aa
commit 6288eff599
17 changed files with 193 additions and 65 deletions

View file

@ -25,14 +25,29 @@ def finalize_frame
click_button "done"
end
def within_frame_preview
within find(".post") do
yield
end
def assert_post_renders_with(template_name)
find(".post")["data-template"].should == template_name.downcase
end
def assert_post_renders_with(template_name)
find(".post")["data-template"].should == template_name
def find_image_by_filename(filename)
find("img[src='#{@image_sources[filename]}']")
end
def store_image_filename(file_name)
@image_sources ||= {}
@image_sources[file_name] = all(".photos img").last["src"]
@image_sources[file_name].should be_present
end
def upload_photo(file_name)
orig_photo_count = all(".photos img").size
within ".new_photo" do
attach_file "photo[user_file]", Rails.root.join("spec", "fixtures", file_name)
wait_until { all(".photos img").size == orig_photo_count + 1 }
end
store_image_filename(file_name)
end
When /^I trumpet$/ do
@ -60,21 +75,13 @@ Then /^"([^"]*)" should be a (limited|public) post in my stream$/ do |post_text,
end
When /^I upload a fixture picture with filename "([^"]*)"$/ do |file_name|
orig_photo_count = all(".photos img").size
within ".new_photo" do
attach_file "photo[user_file]", Rails.root.join("spec", "fixtures", file_name)
wait_until { all(".photos img").size == orig_photo_count + 1 }
end
@image_sources ||= {}
@image_sources[file_name] = all(".photos img").last["src"]
@image_sources[file_name].should be_present
upload_photo(file_name)
end
Then /^"([^"]*)" should have the "([^"]*)" picture$/ do |post_text, file_name|
image = find_post_by_text(post_text).find(".photo_attachments img[src='#{@image_sources[file_name]}']")
image.should be_present
within find_post_by_text(post_text) do
find_image_by_filename(file_name).should be_present
end
end
When /^I go through the default composer$/ do
@ -95,13 +102,19 @@ Then /^"([^"]*)" should have (\d+) pictures$/ do |post_text, number_of_pictures|
end
Then /^I should see "([^"]*)" in the framer preview$/ do |post_text|
within_frame_preview { page.should have_content(post_text) }
within(find(".post")) { page.should have_content(post_text) }
end
When /^I select the template "([^"]*)"$/ do |template_name|
When /^I select the mood "([^"]*)"$/ do |template_name|
select template_name, :from => 'template'
end
Then /^the post should (?:still |)be rendered as a "([^"]*)"$/ do |template_name|
Then /^the post's mood should (?:still |)be "([^"]*)"$/ do |template_name|
assert_post_renders_with(template_name)
end
When /^"([^"]*)" should be in the post's picture viewer$/ do |file_name|
within(".photo_viewer") do
find_image_by_filename(file_name).should be_present
end
end

View file

@ -42,13 +42,18 @@ Feature: Creating a new post
Scenario: Framing your frame
When I write "This is hella customized"
And I upload a fixture picture with filename "button.gif"
And I start the framing process
Then I should see "This is hella customized" in the framer preview
# And I should see the image "button.gif" background
When I select the template "note"
Then the post should be rendered as a "note"
# Then the default mood for the post should be "Wallpaper"
# And I should see the image "button.gif" background
When I select the mood "Day"
Then the post's mood should be "Day"
And "button.gif" should be in the post's picture viewer
And I should see "This is hella customized" in the framer preview
When I finalize my frame
And I go to "/stream"
Then "This is hella customized" should be post 1
When I click the show page link for "This is hella customized"
Then the post should still be rendered as a "note"
And I click the show page link for "This is hella customized"
And the post's mood should still be "Day"

View file

@ -90,4 +90,19 @@ app.models.Post = Backbone.Model.extend({
self.trigger('interacted', this)
}});
}
}, {
frameMoods : [
"Day"
],
legacyTemplateNames : [
"status-with-photo-backdrop",
"note",
"rich-media",
"multi-photo",
"photo-backdrop",
"activity-streams-photo",
"status"
]
});

View file

@ -14,28 +14,14 @@ app.pages.Framer = app.views.Base.extend({
initialize : function(){
this.model = app.frame
this.model.authorIsCurrentUser = function(){ return true }
this.model.bind("change", this.render, this)
this.templatePicker = new app.views.TemplatePicker({ model: this.model })
},
postView : function(){
//we might be leaky like cray cray with this
var templateType = this.model.get("frame_name")
this._postView = new app.views.Post({
model : this.model,
className : templateType + " post loaded",
templateName : "post-viewer/content/" + templateType,
attributes : {"data-template" : templateType}
});
this._postView.feedbackView = new Backbone.View
this.model.authorIsCurrentUser = function(){ return true }
return this._postView
return app.views.Post.showFactory(this.model)
},
saveFrame : function(){

View file

@ -25,14 +25,7 @@ app.pages.PostViewer = app.views.Base.extend({
this.authorView = new app.views.PostViewerAuthor({ model : this.model });
this.interactionsView = new app.views.PostViewerInteractions({ model : this.model });
this.navView = new app.views.PostViewerNav({ model : this.model });
var frameName = this.model.get("frame_name")
this.postView = new app.views.Post({
model : this.model,
className : frameName + " post loaded",
templateName : "post-viewer/content/" + frameName,
attributes : {"data-template" : frameName}
});
this.postView = app.views.Post.showFactory(this.model)
this.render();
},

View file

@ -0,0 +1,2 @@
<section class="text">{{{text}}}</section>
<section class="photo_viewer"></section>

View file

@ -0,0 +1,3 @@
{{#each photos}}
<img src="{{sizes.large}}"/>
{{/each}}

View file

@ -40,7 +40,9 @@ app.views.Base = Backbone.View.extend({
renderTemplate : function(){
var presenter = _.isFunction(this.presenter) ? this.presenter() : this.presenter
this.template = JST[this.templateName]
$(this.el).html(this.template(presenter));
$(this.el)
.html(this.template(presenter))
.attr("data-template", _.last(this.templateName.split("/")));
this.postRenderTemplate();
},

View file

@ -0,0 +1,7 @@
app.views.PhotoViewer = app.views.Base.extend({
templateName : "photo-viewer",
presenter : function(){
return { photos : this.model.get("photos") } //json array of attributes, not backbone models, yet.
}
});

View file

@ -0,0 +1,16 @@
app.views.Post.Day = app.views.Post.extend({
templateName : "day",
className : "day post loaded",
subviews : { "section.photo_viewer" : "photoViewer" },
photoViewer : function(){
return new app.views.PhotoViewer({ model : this.model })
},
postRenderTemplate : function(){
if(this.model.get("text").length < 140){
this.$('section.text').addClass('headline');
}
}
});

View file

@ -1,8 +1,4 @@
app.views.Post = app.views.StreamObject.extend({
initialize : function(options) {
this.templateName = options.templateName
},
presenter : function() {
return _.extend(this.defaultPresenter(), {
authorIsCurrentUser : this.authorIsCurrentUser(),
@ -18,4 +14,31 @@ app.views.Post = app.views.StreamObject.extend({
showPost : function() {
return (app.currentUser.get("showNsfw")) || !this.model.get("nsfw")
}
}, { //static methods below
showFactory : function(model) {
var frameName = model.get("frame_name");
if(_.include(app.models.Post.legacyTemplateNames, frameName)){
return legacyShow(model)
} else {
return new app.views.Post[frameName]({
model : model
})
}
function legacyShow(model) {
return new app.views.Post.Legacy({
model : model,
className : frameName + " post loaded",
templateName : "post-viewer/content/" + frameName
});
}
}
});
app.views.Post.Legacy = app.views.Post.extend({
initialize : function(options) {
this.templateName = options.templateName || this.templateName
}
})

View file

@ -19,15 +19,7 @@ app.views.TemplatePicker = app.views.Base.extend({
presenter : function() {
return _.extend(this.defaultPresenter(), {
templates : [
"status-with-photo-backdrop",
"note",
"rich-media",
"multi-photo",
"photo-backdrop",
"activity-streams-photo",
"status"
]
templates : _.union(app.models.Post.frameMoods, app.models.Post.legacyTemplateNames)
})
}
})

View file

@ -805,3 +805,7 @@ text-rendering: optimizelegibility;
position: absolute;
}
}
.headline p{
@include media-text();
}

View file

@ -10,7 +10,7 @@ describe("app.pages.Framer", function(){
});
it("passes the model down to the post view", function(){
expect(this.page._postView.model).toBe(app.frame)
expect(this.page.postView().model).toBe(app.frame)
});
describe("rendering", function(){

View file

@ -0,0 +1,19 @@
describe("app.views.PhotoViewer", function(){
beforeEach(function(){
this.model = factory.post({
photos : [
factory.photoAttrs({sizes : {large : "http://tieguy.org/me.jpg"}}),
factory.photoAttrs({sizes : {large : "http://whatthefuckiselizabethstarkupto.com/none_knows.gif"}}) //SIC
]
})
this.view = new app.views.PhotoViewer({model : this.model})
})
describe("rendering", function(){
it("should have an image for each photoAttr on the model", function(){
this.view.render()
expect(this.view.$("img").length).toBe(2)
expect(this.view.$("img[src='http://tieguy.org/me.jpg']")).toExist()
})
})
})

View file

@ -0,0 +1,34 @@
describe("app.views.Post.Day", function(){
beforeEach(function(){
this.post = factory.post()
this.view = new app.views.Post.Day({model : this.post})
})
describe("rendering", function(){
it("is happy", function(){
this.view.render()
})
describe("when the text is under 140 characters", function(){
it("has class headline", function(){
this.post.set({text : "Lol this is a short headline"})
this.view.render()
expect(this.view.$("section.text")).toHaveClass("headline")
})
})
describe("when the text is over 140 characters", function(){
it("has doesn't have headline", function(){
this.post.set({text :"Vegan bushwick tempor labore. Nulla seitan anim, aesthetic ex gluten-free viral" +
"thundercats street art. Occaecat carles deserunt lomo messenger bag wes anderson. Narwhal cray selvage " +
"dolor. Mixtape wes anderson american apparel, mustache readymade cred nulla squid veniam small batch id " +
"cupidatat. Pork belly high life consequat, raw denim sint terry richardson seitan single-origin coffee " +
"butcher. Sint yr fugiat cillum."
})
this.view.render()
expect(this.view.$("section.text")).not.toHaveClass("headline")
})
})
})
})

View file

@ -74,6 +74,20 @@ factory = {
}
},
photoAttrs : function(overrides){
return _.extend({
author: factory.userAttrs(),
created_at: "2012-03-27T20:11:52Z",
guid: "8b0db16a4c4307b2",
id: 117,
sizes: {
large: "http://localhost:3000/uploads/images/scaled_full_d85410bd19db1016894c.jpg",
medium: "http://localhost:3000/uploads/images/thumb_medium_d85410bd19db1016894c.jpg",
small: "http://localhost:3000/uploads/images/thumb_small_d85410bd19db1016894c.jpg"
}
}, overrides)
},
post : function(overrides) {
defaultAttrs = _.extend(factory.postAttrs(), {"author" : this.author()})
return new app.models.Post(_.extend(defaultAttrs, overrides))