Looking Good!
-Welcome to Diaspora!
+
Getting started
-Here’s how to get rolling:
+Welcome, friend.
+You're about to change the Internet. Let's get you set up, shall we?
--
+
-
-
check all of your settings!
-look at config/app_config.yml.example for help
+Configure your pod
+
+ Look at
config/app_config.yml.exampleandconfig/database.yml.examplefor help. -
-
Make a new user!
-click on the login link to make it happen
+Try it out
+
+ Start by creating an account.
-
-
Tell us what you think!
-make bug reports, feature requests at: our bug tracker
+Make a contribution!
+
+ Make Diaspora even better! Fork the project on github, make some changes, and submit a pull request.
+
+
+ +
+
- +
+ +
+ + +
Useful Resources
+-
+
- Codebase +
- Documentation +
- Find & Report bugs +
-
+
+
+
+ +
+ +
app/views/home/_show.html.haml
are
some
new
lines" - end - - it 'should render newlines and basic http links correctly' do - message = "Some text, then a line break and a link\nhttp://joindiaspora.com\nsome more text" - res = markdownify(message) - res.should == 'Some text, then a line break and a link
joindiaspora.com
some more text' - end - end - - describe '#person_link' do - before do - @person = Factory(:person) - end - it 'includes the name of the person if they have a first name' do - person_link(@person).should include @person.profile.first_name - end - - it 'uses diaspora handle if the person has no first or last name' do - @person.profile.first_name = nil - @person.profile.last_name = nil - - person_link(@person).should include @person.diaspora_handle - end - - it 'uses diaspora handle if first name and first name are rails#blank?' do - @person.profile.first_name = " " - @person.profile.last_name = " " - - person_link(@person).should include @person.diaspora_handle - end - - it "should not allow basic XSS/HTML" do - @person.profile.first_name = "I'm
Evil"
- @person.profile.last_name = "I'm Evil"
- person_link(@person).should_not include("")
- end
- end
- context 'performance' do
- before do
- @message = "HHello,Hello_, I _am a strong robot.*Hello, I am *a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a **strong robot.Hello, I am _a _strong *robot**.Hello*, I am a strong "
- end
- it 'is sub millisecond' do
- Benchmark.realtime{
- markdownify(@message)
- }.should < 0.001
- end
+ it "should not allow basic XSS/HTML" do
+ @person.profile.first_name = "I'm Evil"
+ @person.profile.last_name = "I'm Evil"
+ person_link(@person).should_not include("")
end
end
end
diff --git a/spec/helpers/layout_helper_spec.rb b/spec/helpers/layout_helper_spec.rb
new file mode 100644
index 000000000..3bf5c1359
--- /dev/null
+++ b/spec/helpers/layout_helper_spec.rb
@@ -0,0 +1,38 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe LayoutHelper do
+ before do
+ @user = alice
+ end
+
+ describe "#page_title" do
+ before do
+ def current_user
+ @current_user
+ end
+ end
+
+ context "passed blank text" do
+ it "returns current_user.name if logged in" do
+ @current_user = @user
+ page_title.should == @user.name
+ end
+
+ it "returns default title if not logged in" do
+ @current_user = nil
+ page_title.should == I18n.t("application.helper.diaspora_alpha")
+ end
+ end
+
+ context "passed text" do
+ it "returns the text" do
+ text = "This is the title"
+ page_title(text).should == text
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/helpers/markdownify_helper_spec.rb b/spec/helpers/markdownify_helper_spec.rb
new file mode 100644
index 000000000..e292490d4
--- /dev/null
+++ b/spec/helpers/markdownify_helper_spec.rb
@@ -0,0 +1,239 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe MarkdownifyHelper do
+ describe "#markdownify" do
+ describe "autolinks" do
+ it "should not allow basic XSS/HTML" do
+ markdownify("").should == "<script>alert('XSS is evil')</script>"
+ end
+
+ it "should recognize basic http links (1/3)" do
+ proto="http"
+ url="bugs.joindiaspora.com/issues/332"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize basic http links (2/3)" do
+ proto="http"
+ url="webmail.example.com?~()!*/"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize basic http links (3/3)" do
+ proto="http"
+ url="127.0.0.1:3000/users/sign_in"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize secure https links" do
+ proto="https"
+ url="127.0.0.1:3000/users/sign_in"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ describe "video links" do
+ it "recognizes vimeo links" do
+ video_id = "17449557"
+ url = "http://www.vimeo.com/#{video_id}"
+ res = markdownify(url)
+ res.should =~ /data-host="vimeo.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "recognizes youtube links" do
+ video_id = "0x__dDWdf23"
+ url = "http://www.youtube.com/watch?v=" + video_id + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "recognizes youtube links with hyphens" do
+ video_id = "ABYnqp-bxvg"
+ url = "http://www.youtube.com/watch?v=" + video_id + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "keeps anchors" do
+ anchor = "#t=11m34"
+ video_id = "DHRoHuv3I8E"
+ url = "http://www.youtube.com/watch?v=" + video_id + anchor
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ res.should =~ /data-anchor="#{anchor}"/
+ end
+
+ it "has an empty data-anchor attribute if there is no anchor" do
+ video_id = "DHRoHuv3I8E"
+ url = "http://www.youtube.com/watch?v=" + video_id
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ res.should =~ /data-anchor=""/
+ end
+
+ it "leaves the links in the href of the #a tag" do
+ video_id = "ABYnqp-bxvg"
+ start_url ="http://www.youtube.com/watch?v=" + video_id
+ url = start_url + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /href=[\S]+v=#{video_id}/
+ end
+
+ it 'does not autolink inside the link' do
+ video_id = "ABYnqp-bxvg"
+ start_url ="http://www.youtube.com/watch?v=" + video_id
+ url = start_url + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.match(/href=""+url+""
+ end
+
+ it "should recognize www links" do
+ url="www.joindiaspora.com"
+ markdownify(url).should == ""+url+""
+ end
+ end
+
+ describe "emoticons" do
+ it "replaces <3 with ♥" do
+ message = "i <3 you"
+ markdownify(message).should == "i ♥ you"
+ end
+
+ it "replaces various things with (their) HTML entities" do
+ message = ":) :-) :( :-( ... -> <- (tm) (r) (c)"
+ markdownify(message).should == "☺ ☺ ☹ ☹ … → ← ™ ® ©"
+ end
+
+ it "skips doing it if you say so" do
+ message = ":) :-) :( :-( ... -> <-"
+ markdownify(message, :emoticons => false).should == ":) :-) :( :-( ... -> <-"
+ end
+ end
+
+ describe "weak emphasis" do
+ it "should be recognized (1/2)" do
+ message = "*some text* some text *some text* some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+
+ it "should be recognized (2/2)" do
+ message = "_some text_ some text _some text_ some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+ end
+
+ describe "strong emphasis" do
+ it "should be recognized (1/2)" do
+ message = "**some text** some text **some text** some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+
+ it "should be recognized (2/2)" do
+ message = "__some text__ some text __some text__ some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+ end
+
+ describe "nested weak and strong emphasis" do
+ it "should be rendered correctly" do
+ message = "__this is _some_ text__"
+ markdownify(message).should == "this is some text"
+ message = "*this is **some** text*"
+ markdownify(message).should == "this is some text"
+ message = "___some text___"
+ markdownify(message).should == "some text"
+ end
+ end
+
+ describe "links" do
+ it "should be recognized without title attribute" do
+ message = "[link text](http://someurl.com) [link text](http://someurl.com)"
+ markdownify(message).should == 'link text link text'
+ end
+
+ it "should be recognized with title attribute" do
+ message = '[link text](http://someurl.com "some title") [link text](http://someurl.com "some title")'
+ markdownify(message).should == 'link text link text'
+ end
+
+ it "should have a robust link parsing" do
+ message = "This [*text*](http://en.wikipedia.org/wiki/Text_(literary_theory)) with many [links](google.com) tests [_http_](http://google.com/search?q=with_multiple__underscores*and**asterisks), [___FTP___](ftp://ftp.uni-kl.de/CCC/26C3/mp4/26c3-3540-en-a_hackers_utopia.mp4 \"File Transfer Protocol\"), [**any protocol**](foo://bar.example.org/yes_it*makes*no_sense)"
+ markdownify(message).should == 'This text with many links tests http, FTP, any protocol'
+ end
+ end
+
+ describe "nested emphasis and links tags" do
+ it "should be rendered correctly" do
+ message = '[**some *link* text**](someurl.com "some title")'
+ markdownify(message).should == 'some link text'
+ end
+ end
+
+ it "should allow escaping" do
+ message = '*some text* \\*some text* \\**some text* _some text_ \\_some text_ \\__some text_'
+ markdownify(message).should == "some text *some text **some text some text _some text __some text"
+ end
+
+ describe "newlines" do
+ it 'skips inserting newlines if you pass the newlines option' do
+ message = "These\nare\n\some\nnew\lines"
+ res = markdownify(message, :newlines => false)
+ res.should == message
+ end
+
+ it 'generates breaklines' do
+ message = "These\nare\nsome\nnew\nlines"
+ res = markdownify(message)
+ res.should == "These
are
some
new
lines"
+ end
+
+ it 'should render newlines and basic http links correctly' do
+ message = "Some text, then a line break and a link\nhttp://joindiaspora.com\nsome more text"
+ res = markdownify(message)
+ res.should == 'Some text, then a line break and a link
joindiaspora.com
some more text'
+ end
+ end
+
+ context 'performance' do
+ before do
+ @message = "HHello,Hello_, I _am a strong robot.*Hello, I am *a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a **strong robot.Hello, I am _a _strong *robot**.Hello*, I am a strong "
+ end
+
+ it 'is sub millisecond' do
+ Benchmark.realtime{
+ markdownify(@message)
+ }.should < 0.001
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/helpers/stream_helper_spec.rb b/spec/helpers/stream_helper_spec.rb
new file mode 100644
index 000000000..ebb6ce0b7
--- /dev/null
+++ b/spec/helpers/stream_helper_spec.rb
@@ -0,0 +1,24 @@
+# Copyright (c) 2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe StreamHelper do
+ before do
+ @post = Factory(:status_message)
+ end
+ describe "#time_for_sort" do
+ it "returns sort_order for an aspectscontroller" do
+ sort_order = :stored_in_session
+ stub!(:controller).and_return(AspectsController.new)
+ stub!(:session).and_return({:sort_order => sort_order})
+ @post.should_receive(sort_order)
+ time_for_sort(@post)
+ end
+ it "returns post.created_at otherwise" do
+ stub!(:controller).and_return(mock())
+ time_for_sort(@post).should == @post.created_at
+ end
+ end
+end
diff --git a/spec/javascripts/content-updater-spec.js b/spec/javascripts/content-updater-spec.js
new file mode 100644
index 000000000..df0bc5ae0
--- /dev/null
+++ b/spec/javascripts/content-updater-spec.js
@@ -0,0 +1,34 @@
+/* Copyright (c) 2010, Diaspora Inc. This file is
+* licensed under the Affero General Public License version 3 or later. See
+* the COPYRIGHT file.
+*/
+
+describe("ContentUpdater", function() {
+ describe("addPostToStream", function() {
+
+ beforeEach(function() {
+ $("#jasmine_content").empty();
+ spec.loadFixture("aspects_index");
+ });
+
+ it("adds a post to the stream", function() {
+ var originalPostCount = $(".stream_element").length;
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ });
+
+ it("does not add duplicate posts", function() {
+ var originalPostCount = $(".stream_element").length;
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ });
+
+ it("removes the div that says you have no posts if it exists", function() {
+ expect($("#no_posts").length).toEqual(1);
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($("#no_posts").length).toEqual(0);
+ });
+ });
+});
diff --git a/spec/javascripts/stream-spec.js b/spec/javascripts/stream-spec.js
index 19b6e71e6..4b0a16275 100644
--- a/spec/javascripts/stream-spec.js
+++ b/spec/javascripts/stream-spec.js
@@ -6,31 +6,7 @@
describe("Stream", function() {
beforeEach(function() {
jasmine.Clock.useMock();
- $('#jasmine_content').html(
- '' +
- '' +
- '' +
- '' +
- 'show comments (0)' +
- '' +
- '' +
- '' +
- ' ' +
- ''
- );
+ spec.loadFixture('aspects_index_with_posts');
});
describe("initialize", function() {
@@ -48,16 +24,17 @@ describe("Stream", function() {
Stream.initialize();
});
it("toggles class hidden on the comment block", function () {
- expect(jQuery('ul.comments')).toHaveClass("hidden");
+ expect(jQuery('ul.comments')).not.toHaveClass("hidden");
$("a.show_post_comments").click();
jasmine.Clock.tick(200);
- expect(jQuery('ul.comments')).not.toHaveClass("hidden");
+ expect(jQuery('ul.comments')).toHaveClass("hidden");
});
it("changes the text on the show comments link", function() {
+ expect($("a.show_post_comments").text()).toEqual("hide comments (1)");
$("a.show_post_comments").click();
jasmine.Clock.tick(200);
- expect($("a.show_post_comments").text()).toEqual("hide comments (0)");
+ expect($("a.show_post_comments").text()).toEqual("show comments (1)");
});
});
});
diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml
index de698e936..707fb41ad 100644
--- a/spec/javascripts/support/jasmine.yml
+++ b/spec/javascripts/support/jasmine.yml
@@ -30,6 +30,7 @@ src_files:
- public/javascripts/widgets/directionDetector.js
- public/javascripts/widgets/infinite-scroll.js
- public/javascripts/widgets/notifications.js
+ - public/javascripts/widgets/flashes.js
- public/javascripts/mobile.js
- public/javascripts/contact-list.js
- public/javascripts/web-socket-receiver.js
@@ -39,6 +40,7 @@ src_files:
- public/javascripts/validation.js
- public/javascripts/rails.js
- public/javascripts/aspect-filters.js
+ - public/javascripts/content-updater.js
# stylesheets
#
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
diff --git a/spec/javascripts/view-spec.js b/spec/javascripts/view-spec.js
index ba3a3600f..a2e9eefbe 100644
--- a/spec/javascripts/view-spec.js
+++ b/spec/javascripts/view-spec.js
@@ -42,33 +42,6 @@ describe("View", function() {
});
});
- describe("flashes", function() {
- describe("animate", function() {
- beforeEach(function() {
- $("#jasmine_content").html(
- '' +
- 'flash! flash! flash!' +
- ''
- );
- });
-
- it("is called when the DOM is ready", function() {
- spyOn(View.flashes, "animate").andCallThrough();
- View.initialize();
- expect(View.flashes.animate).toHaveBeenCalled();
- });
- });
- describe("render", function() {
- it("creates a new div and calls flashes.animate", function() {
- spyOn(View.flashes, "animate");
- View.flashes.render({
- success: true,
- message: "success!"
- });
- expect(View.flashes.animate).toHaveBeenCalled();
- });
- });
- });
describe("newRequest", function() {
beforeEach(function() {
diff --git a/spec/javascripts/widgets/flashes-spec.js b/spec/javascripts/widgets/flashes-spec.js
new file mode 100644
index 000000000..1ac7061e9
--- /dev/null
+++ b/spec/javascripts/widgets/flashes-spec.js
@@ -0,0 +1,32 @@
+describe("Diaspora", function() {
+ describe("widgets", function() {
+ describe("flashes", function() {
+ describe("animateMessages", function() {
+ beforeEach(function() {
+ $("#jasmine_content").html(
+ '' +
+ 'flash message' +
+ ''
+ );
+ });
+
+ it("is called when the DOM is ready", function() {
+ spyOn(Diaspora.widgets.flashes, "animateMessages").andCallThrough();
+ Diaspora.widgets.flashes.start();
+ expect(Diaspora.widgets.flashes.animateMessages).toHaveBeenCalled();
+ });
+ });
+
+ describe("render", function() {
+ it("creates a new div for the message and calls flashes.animateMessages", function() {
+ spyOn(Diaspora.widgets.flashes, "animateMessages");
+ Diaspora.widgets.flashes.render({
+ success: true,
+ message: "success!"
+ });
+ expect(Diaspora.widgets.flashes.animateMessages).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/spec/javascripts/widgets/notifications-spec.js b/spec/javascripts/widgets/notifications-spec.js
index aeedf1d57..c68854205 100644
--- a/spec/javascripts/widgets/notifications-spec.js
+++ b/spec/javascripts/widgets/notifications-spec.js
@@ -50,6 +50,18 @@ describe("Diaspora", function() {
expect($("#notifications div").length).toEqual(1);
});
+
+ it("only increments the notification count if specified to do so", function() {
+ var originalCount = Diaspora.widgets.notifications.count;
+
+ Diaspora.widgets.notifications.showNotification({
+ html: '',
+ incrementCount: false
+ });
+
+ expect(Diaspora.widgets.notifications.count).toEqual(originalCount);
+
+ });
});
});
});
diff --git a/spec/lib/youtube_titles_spec.rb b/spec/lib/youtube_titles_spec.rb
index d9c82a84f..82e6ec107 100644
--- a/spec/lib/youtube_titles_spec.rb
+++ b/spec/lib/youtube_titles_spec.rb
@@ -1,29 +1,35 @@
require 'spec_helper'
require 'youtube_titles'
+
describe YoutubeTitles do
+ include YoutubeTitles
+
before do
@video_id = "ABYnqp-bxvg"
@url="http://www.youtube.com/watch?v=#{@video_id}&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
@api_path = "/feeds/api/videos/#{@video_id}?v=2"
end
- include YoutubeTitles
+
describe '#youtube_title_for' do
before do
@expected_title = "UP & down & UP & down &"
@mock_http = mock("http")
Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(@mock_http)
end
+
it 'gets a youtube title corresponding to an id' do
@mock_http.should_receive(:get).with(@api_path, nil).and_return(
[nil, "Foobar #{@expected_title} hallo welt dsd"])
youtube_title_for(@video_id).should == @expected_title
end
+
it 'returns a fallback for videos with no title' do
@mock_http.should_receive(:get).with(@api_path, nil).and_return(
[nil, "Foobar #{@expected_title} hallo welt dsd"])
youtube_title_for(@video_id).should == I18n.t('application.helper.video_title.unknown')
end
end
+
describe 'serialization and marshalling' do
before do
@expected_title = '""Procrastination"" Tales Of Mere Existence'
@@ -33,10 +39,34 @@ describe YoutubeTitles do
[nil, "Foobar #{@expected_title} hallo welt dsd"])
@post = Factory.create(:status_message, :text => @url)
end
+
it 'can be re-marshalled' do
lambda {
StatusMessage.find(@post.id).youtube_titles
}.should_not raise_error
end
end
+
+ describe "YOUTUBE_ID_REGEX" do
+ specify "normal url" do
+ url = "http://www.youtube.com/watch?v=dQw4w9WgXcQ"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+
+ specify "https url" do
+ url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+
+ specify "url with extra query params" do
+ url = "http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=related"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+ end
end
diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb
index 344f99946..40c062067 100644
--- a/spec/mailers/notifier_spec.rb
+++ b/spec/mailers/notifier_spec.rb
@@ -83,11 +83,11 @@ describe Notifier do
end
it 'has the receivers name in the body' do
- @mail.body.encoded.include?(@user.person.profile.first_name).should be true
+ @mail.body.encoded.include?(@user.person.profile.first_name).should be_true
end
it 'has the name of person mentioning in the body' do
- @mail.body.encoded.include?(@sm.author.name).should be true
+ @mail.body.encoded.include?(@sm.author.name).should be_true
end
it 'has the post text in the body' do
@@ -99,6 +99,30 @@ describe Notifier do
end
end
+ describe ".liked" do
+ before do
+ @sm = Factory(:status_message, :author => alice.person)
+ @like = @sm.likes.create(:author => bob.person)
+ @mail = Notifier.liked(alice.id, @like.author.id, @like.id)
+ end
+
+ it 'goes to the right person' do
+ @mail.to.should == [alice.email]
+ end
+
+ it 'has the receivers name in the body' do
+ @mail.body.encoded.include?(alice.person.profile.first_name).should be true
+ end
+
+ it 'has the name of person liking in the body' do
+ @mail.body.encoded.include?(@like.author.name).should be_true
+ end
+
+ it 'should not include translation missing' do
+ @mail.body.encoded.should_not include("missing")
+ end
+ end
+
describe ".private_message" do
before do
@user2 = bob
@@ -135,6 +159,7 @@ describe Notifier do
@mail.body.encoded.should_not include("missing")
end
end
+
context "comments" do
let!(:connect) { connect_users(user, aspect, user2, aspect2)}
let!(:sm) {user.post(:status_message, :text => "Sunny outside", :to => :all)}
diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb
index bf754590a..f844c2ab7 100644
--- a/spec/models/comment_spec.rb
+++ b/spec/models/comment_spec.rb
@@ -92,20 +92,22 @@ describe Comment do
before do
@message = alice.post :status_message, :text => "hi", :to => @alices_aspect.id
end
+
it 'should process youtube titles on the way in' do
- video_id = "ABYnqp-bxvg"
- url="http://www.youtube.com/watch?v=#{video_id}&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
- expected_title = "UP & down & UP & down &"
+ first_video_id = "ABYnqp-1111"
+ second_video_id = "ABYnqp-2222"
+ url = "http://www.youtube.com/watch?v=#{first_video_id} http://www.youtube.com/watch?v=#{second_video_id}"
+ expected_title = "UP & down & UP & down &"
mock_http = mock("http")
- Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(mock_http)
- mock_http.should_receive(:get).with('/feeds/api/videos/'+video_id+'?v=2', nil).and_return(
+ Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).twice.and_return(mock_http)
+ mock_http.should_receive(:get).with(/\/feeds\/api\/videos/, nil).twice.and_return(
[nil, 'Foobar '+expected_title+' hallo welt dsd'])
comment = alice.build_comment url, :on => @message
-
comment.save!
- Comment.find(comment.id).youtube_titles.should == {video_id => CGI::escape(expected_title)}
+
+ Comment.find(comment.id).youtube_titles.should == { first_video_id => CGI::escape(expected_title), second_video_id => CGI::escape(expected_title) }
end
end
diff --git a/spec/models/like_spec.rb b/spec/models/like_spec.rb
index 9fea70324..8bdc4ca25 100644
--- a/spec/models/like_spec.rb
+++ b/spec/models/like_spec.rb
@@ -12,7 +12,7 @@ describe Like do
@bob = bob
@eve = eve
- @status = alice.post(:status_message, :text => "hello", :to => @alices_aspect.id)
+ @status = bob.post(:status_message, :text => "hello", :to => @alices_aspect.id)
end
describe 'User#like' do
@@ -34,6 +34,24 @@ describe Like do
end
end
+ describe '#notification_type' do
+ before do
+ @like = @alice.like(1, :on => @status)
+ end
+
+ it 'should be notifications liked if you are the post owner' do
+ @like.notification_type(@bob, @alice.person).should be Notifications::Liked
+ end
+
+ it 'should not notify you if you are the like-r' do
+ @like.notification_type(@alice, @alice.person).should be_nil
+ end
+
+ it 'should not notify you if you did not create the post' do
+ @like.notification_type(@eve, @alice.person).should be_nil
+ end
+ end
+
describe 'xml' do
before do
@liker = Factory.create(:user)
@@ -67,11 +85,11 @@ describe Like do
@local_luke, @local_leia, @remote_raphael = set_up_friends
@remote_parent = Factory.create(:status_message, :author => @remote_raphael)
@local_parent = @local_luke.post :status_message, :text => "foobar", :to => @local_luke.aspects.first
-
+
@object_by_parent_author = @local_luke.like(1, :on => @local_parent)
@object_by_recipient = @local_leia.build_like(1, :on => @local_parent)
@dup_object_by_parent_author = @object_by_parent_author.dup
-
+
@object_on_remote_parent = @local_luke.like(0, :on => @remote_parent)
end
it_should_behave_like 'it is relayable'
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 7d093669d..a617782e2 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -40,6 +40,10 @@ RSpec.configure do |config|
$process_queue = false
end
+
+ config.before(:each, :type => :controller) do
+ self.class.render_views
+ end
end
disable_typhoeus
")
- end
- end
- context 'performance' do
- before do
- @message = "HHello,Hello_, I _am a strong robot.*Hello, I am *a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a **strong robot.Hello, I am _a _strong *robot**.Hello*, I am a strong "
- end
- it 'is sub millisecond' do
- Benchmark.realtime{
- markdownify(@message)
- }.should < 0.001
- end
+ it "should not allow basic XSS/HTML" do
+ @person.profile.first_name = "I'm Evil"
+ @person.profile.last_name = "I'm Evil"
+ person_link(@person).should_not include("")
end
end
end
diff --git a/spec/helpers/layout_helper_spec.rb b/spec/helpers/layout_helper_spec.rb
new file mode 100644
index 000000000..3bf5c1359
--- /dev/null
+++ b/spec/helpers/layout_helper_spec.rb
@@ -0,0 +1,38 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe LayoutHelper do
+ before do
+ @user = alice
+ end
+
+ describe "#page_title" do
+ before do
+ def current_user
+ @current_user
+ end
+ end
+
+ context "passed blank text" do
+ it "returns current_user.name if logged in" do
+ @current_user = @user
+ page_title.should == @user.name
+ end
+
+ it "returns default title if not logged in" do
+ @current_user = nil
+ page_title.should == I18n.t("application.helper.diaspora_alpha")
+ end
+ end
+
+ context "passed text" do
+ it "returns the text" do
+ text = "This is the title"
+ page_title(text).should == text
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/helpers/markdownify_helper_spec.rb b/spec/helpers/markdownify_helper_spec.rb
new file mode 100644
index 000000000..e292490d4
--- /dev/null
+++ b/spec/helpers/markdownify_helper_spec.rb
@@ -0,0 +1,239 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe MarkdownifyHelper do
+ describe "#markdownify" do
+ describe "autolinks" do
+ it "should not allow basic XSS/HTML" do
+ markdownify("").should == "<script>alert('XSS is evil')</script>"
+ end
+
+ it "should recognize basic http links (1/3)" do
+ proto="http"
+ url="bugs.joindiaspora.com/issues/332"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize basic http links (2/3)" do
+ proto="http"
+ url="webmail.example.com?~()!*/"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize basic http links (3/3)" do
+ proto="http"
+ url="127.0.0.1:3000/users/sign_in"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize secure https links" do
+ proto="https"
+ url="127.0.0.1:3000/users/sign_in"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ describe "video links" do
+ it "recognizes vimeo links" do
+ video_id = "17449557"
+ url = "http://www.vimeo.com/#{video_id}"
+ res = markdownify(url)
+ res.should =~ /data-host="vimeo.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "recognizes youtube links" do
+ video_id = "0x__dDWdf23"
+ url = "http://www.youtube.com/watch?v=" + video_id + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "recognizes youtube links with hyphens" do
+ video_id = "ABYnqp-bxvg"
+ url = "http://www.youtube.com/watch?v=" + video_id + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "keeps anchors" do
+ anchor = "#t=11m34"
+ video_id = "DHRoHuv3I8E"
+ url = "http://www.youtube.com/watch?v=" + video_id + anchor
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ res.should =~ /data-anchor="#{anchor}"/
+ end
+
+ it "has an empty data-anchor attribute if there is no anchor" do
+ video_id = "DHRoHuv3I8E"
+ url = "http://www.youtube.com/watch?v=" + video_id
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ res.should =~ /data-anchor=""/
+ end
+
+ it "leaves the links in the href of the #a tag" do
+ video_id = "ABYnqp-bxvg"
+ start_url ="http://www.youtube.com/watch?v=" + video_id
+ url = start_url + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /href=[\S]+v=#{video_id}/
+ end
+
+ it 'does not autolink inside the link' do
+ video_id = "ABYnqp-bxvg"
+ start_url ="http://www.youtube.com/watch?v=" + video_id
+ url = start_url + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.match(/href=""+url+""
+ end
+
+ it "should recognize www links" do
+ url="www.joindiaspora.com"
+ markdownify(url).should == ""+url+""
+ end
+ end
+
+ describe "emoticons" do
+ it "replaces <3 with ♥" do
+ message = "i <3 you"
+ markdownify(message).should == "i ♥ you"
+ end
+
+ it "replaces various things with (their) HTML entities" do
+ message = ":) :-) :( :-( ... -> <- (tm) (r) (c)"
+ markdownify(message).should == "☺ ☺ ☹ ☹ … → ← ™ ® ©"
+ end
+
+ it "skips doing it if you say so" do
+ message = ":) :-) :( :-( ... -> <-"
+ markdownify(message, :emoticons => false).should == ":) :-) :( :-( ... -> <-"
+ end
+ end
+
+ describe "weak emphasis" do
+ it "should be recognized (1/2)" do
+ message = "*some text* some text *some text* some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+
+ it "should be recognized (2/2)" do
+ message = "_some text_ some text _some text_ some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+ end
+
+ describe "strong emphasis" do
+ it "should be recognized (1/2)" do
+ message = "**some text** some text **some text** some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+
+ it "should be recognized (2/2)" do
+ message = "__some text__ some text __some text__ some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+ end
+
+ describe "nested weak and strong emphasis" do
+ it "should be rendered correctly" do
+ message = "__this is _some_ text__"
+ markdownify(message).should == "this is some text"
+ message = "*this is **some** text*"
+ markdownify(message).should == "this is some text"
+ message = "___some text___"
+ markdownify(message).should == "some text"
+ end
+ end
+
+ describe "links" do
+ it "should be recognized without title attribute" do
+ message = "[link text](http://someurl.com) [link text](http://someurl.com)"
+ markdownify(message).should == 'link text link text'
+ end
+
+ it "should be recognized with title attribute" do
+ message = '[link text](http://someurl.com "some title") [link text](http://someurl.com "some title")'
+ markdownify(message).should == 'link text link text'
+ end
+
+ it "should have a robust link parsing" do
+ message = "This [*text*](http://en.wikipedia.org/wiki/Text_(literary_theory)) with many [links](google.com) tests [_http_](http://google.com/search?q=with_multiple__underscores*and**asterisks), [___FTP___](ftp://ftp.uni-kl.de/CCC/26C3/mp4/26c3-3540-en-a_hackers_utopia.mp4 \"File Transfer Protocol\"), [**any protocol**](foo://bar.example.org/yes_it*makes*no_sense)"
+ markdownify(message).should == 'This text with many links tests http, FTP, any protocol'
+ end
+ end
+
+ describe "nested emphasis and links tags" do
+ it "should be rendered correctly" do
+ message = '[**some *link* text**](someurl.com "some title")'
+ markdownify(message).should == 'some link text'
+ end
+ end
+
+ it "should allow escaping" do
+ message = '*some text* \\*some text* \\**some text* _some text_ \\_some text_ \\__some text_'
+ markdownify(message).should == "some text *some text **some text some text _some text __some text"
+ end
+
+ describe "newlines" do
+ it 'skips inserting newlines if you pass the newlines option' do
+ message = "These\nare\n\some\nnew\lines"
+ res = markdownify(message, :newlines => false)
+ res.should == message
+ end
+
+ it 'generates breaklines' do
+ message = "These\nare\nsome\nnew\nlines"
+ res = markdownify(message)
+ res.should == "These
are
some
new
lines"
+ end
+
+ it 'should render newlines and basic http links correctly' do
+ message = "Some text, then a line break and a link\nhttp://joindiaspora.com\nsome more text"
+ res = markdownify(message)
+ res.should == 'Some text, then a line break and a link
joindiaspora.com
some more text'
+ end
+ end
+
+ context 'performance' do
+ before do
+ @message = "HHello,Hello_, I _am a strong robot.*Hello, I am *a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a **strong robot.Hello, I am _a _strong *robot**.Hello*, I am a strong "
+ end
+
+ it 'is sub millisecond' do
+ Benchmark.realtime{
+ markdownify(@message)
+ }.should < 0.001
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/helpers/stream_helper_spec.rb b/spec/helpers/stream_helper_spec.rb
new file mode 100644
index 000000000..ebb6ce0b7
--- /dev/null
+++ b/spec/helpers/stream_helper_spec.rb
@@ -0,0 +1,24 @@
+# Copyright (c) 2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe StreamHelper do
+ before do
+ @post = Factory(:status_message)
+ end
+ describe "#time_for_sort" do
+ it "returns sort_order for an aspectscontroller" do
+ sort_order = :stored_in_session
+ stub!(:controller).and_return(AspectsController.new)
+ stub!(:session).and_return({:sort_order => sort_order})
+ @post.should_receive(sort_order)
+ time_for_sort(@post)
+ end
+ it "returns post.created_at otherwise" do
+ stub!(:controller).and_return(mock())
+ time_for_sort(@post).should == @post.created_at
+ end
+ end
+end
diff --git a/spec/javascripts/content-updater-spec.js b/spec/javascripts/content-updater-spec.js
new file mode 100644
index 000000000..df0bc5ae0
--- /dev/null
+++ b/spec/javascripts/content-updater-spec.js
@@ -0,0 +1,34 @@
+/* Copyright (c) 2010, Diaspora Inc. This file is
+* licensed under the Affero General Public License version 3 or later. See
+* the COPYRIGHT file.
+*/
+
+describe("ContentUpdater", function() {
+ describe("addPostToStream", function() {
+
+ beforeEach(function() {
+ $("#jasmine_content").empty();
+ spec.loadFixture("aspects_index");
+ });
+
+ it("adds a post to the stream", function() {
+ var originalPostCount = $(".stream_element").length;
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ });
+
+ it("does not add duplicate posts", function() {
+ var originalPostCount = $(".stream_element").length;
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ });
+
+ it("removes the div that says you have no posts if it exists", function() {
+ expect($("#no_posts").length).toEqual(1);
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($("#no_posts").length).toEqual(0);
+ });
+ });
+});
diff --git a/spec/javascripts/stream-spec.js b/spec/javascripts/stream-spec.js
index 19b6e71e6..4b0a16275 100644
--- a/spec/javascripts/stream-spec.js
+++ b/spec/javascripts/stream-spec.js
@@ -6,31 +6,7 @@
describe("Stream", function() {
beforeEach(function() {
jasmine.Clock.useMock();
- $('#jasmine_content').html(
- '' +
- '' +
- '' +
- '' +
- 'show comments (0)' +
- '' +
- '' +
- '' +
- ' ' +
- ''
- );
+ spec.loadFixture('aspects_index_with_posts');
});
describe("initialize", function() {
@@ -48,16 +24,17 @@ describe("Stream", function() {
Stream.initialize();
});
it("toggles class hidden on the comment block", function () {
- expect(jQuery('ul.comments')).toHaveClass("hidden");
+ expect(jQuery('ul.comments')).not.toHaveClass("hidden");
$("a.show_post_comments").click();
jasmine.Clock.tick(200);
- expect(jQuery('ul.comments')).not.toHaveClass("hidden");
+ expect(jQuery('ul.comments')).toHaveClass("hidden");
});
it("changes the text on the show comments link", function() {
+ expect($("a.show_post_comments").text()).toEqual("hide comments (1)");
$("a.show_post_comments").click();
jasmine.Clock.tick(200);
- expect($("a.show_post_comments").text()).toEqual("hide comments (0)");
+ expect($("a.show_post_comments").text()).toEqual("show comments (1)");
});
});
});
diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml
index de698e936..707fb41ad 100644
--- a/spec/javascripts/support/jasmine.yml
+++ b/spec/javascripts/support/jasmine.yml
@@ -30,6 +30,7 @@ src_files:
- public/javascripts/widgets/directionDetector.js
- public/javascripts/widgets/infinite-scroll.js
- public/javascripts/widgets/notifications.js
+ - public/javascripts/widgets/flashes.js
- public/javascripts/mobile.js
- public/javascripts/contact-list.js
- public/javascripts/web-socket-receiver.js
@@ -39,6 +40,7 @@ src_files:
- public/javascripts/validation.js
- public/javascripts/rails.js
- public/javascripts/aspect-filters.js
+ - public/javascripts/content-updater.js
# stylesheets
#
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
diff --git a/spec/javascripts/view-spec.js b/spec/javascripts/view-spec.js
index ba3a3600f..a2e9eefbe 100644
--- a/spec/javascripts/view-spec.js
+++ b/spec/javascripts/view-spec.js
@@ -42,33 +42,6 @@ describe("View", function() {
});
});
- describe("flashes", function() {
- describe("animate", function() {
- beforeEach(function() {
- $("#jasmine_content").html(
- '' +
- 'flash! flash! flash!' +
- ''
- );
- });
-
- it("is called when the DOM is ready", function() {
- spyOn(View.flashes, "animate").andCallThrough();
- View.initialize();
- expect(View.flashes.animate).toHaveBeenCalled();
- });
- });
- describe("render", function() {
- it("creates a new div and calls flashes.animate", function() {
- spyOn(View.flashes, "animate");
- View.flashes.render({
- success: true,
- message: "success!"
- });
- expect(View.flashes.animate).toHaveBeenCalled();
- });
- });
- });
describe("newRequest", function() {
beforeEach(function() {
diff --git a/spec/javascripts/widgets/flashes-spec.js b/spec/javascripts/widgets/flashes-spec.js
new file mode 100644
index 000000000..1ac7061e9
--- /dev/null
+++ b/spec/javascripts/widgets/flashes-spec.js
@@ -0,0 +1,32 @@
+describe("Diaspora", function() {
+ describe("widgets", function() {
+ describe("flashes", function() {
+ describe("animateMessages", function() {
+ beforeEach(function() {
+ $("#jasmine_content").html(
+ '' +
+ 'flash message' +
+ ''
+ );
+ });
+
+ it("is called when the DOM is ready", function() {
+ spyOn(Diaspora.widgets.flashes, "animateMessages").andCallThrough();
+ Diaspora.widgets.flashes.start();
+ expect(Diaspora.widgets.flashes.animateMessages).toHaveBeenCalled();
+ });
+ });
+
+ describe("render", function() {
+ it("creates a new div for the message and calls flashes.animateMessages", function() {
+ spyOn(Diaspora.widgets.flashes, "animateMessages");
+ Diaspora.widgets.flashes.render({
+ success: true,
+ message: "success!"
+ });
+ expect(Diaspora.widgets.flashes.animateMessages).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/spec/javascripts/widgets/notifications-spec.js b/spec/javascripts/widgets/notifications-spec.js
index aeedf1d57..c68854205 100644
--- a/spec/javascripts/widgets/notifications-spec.js
+++ b/spec/javascripts/widgets/notifications-spec.js
@@ -50,6 +50,18 @@ describe("Diaspora", function() {
expect($("#notifications div").length).toEqual(1);
});
+
+ it("only increments the notification count if specified to do so", function() {
+ var originalCount = Diaspora.widgets.notifications.count;
+
+ Diaspora.widgets.notifications.showNotification({
+ html: '',
+ incrementCount: false
+ });
+
+ expect(Diaspora.widgets.notifications.count).toEqual(originalCount);
+
+ });
});
});
});
diff --git a/spec/lib/youtube_titles_spec.rb b/spec/lib/youtube_titles_spec.rb
index d9c82a84f..82e6ec107 100644
--- a/spec/lib/youtube_titles_spec.rb
+++ b/spec/lib/youtube_titles_spec.rb
@@ -1,29 +1,35 @@
require 'spec_helper'
require 'youtube_titles'
+
describe YoutubeTitles do
+ include YoutubeTitles
+
before do
@video_id = "ABYnqp-bxvg"
@url="http://www.youtube.com/watch?v=#{@video_id}&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
@api_path = "/feeds/api/videos/#{@video_id}?v=2"
end
- include YoutubeTitles
+
describe '#youtube_title_for' do
before do
@expected_title = "UP & down & UP & down &"
@mock_http = mock("http")
Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(@mock_http)
end
+
it 'gets a youtube title corresponding to an id' do
@mock_http.should_receive(:get).with(@api_path, nil).and_return(
[nil, "Foobar #{@expected_title} hallo welt dsd"])
youtube_title_for(@video_id).should == @expected_title
end
+
it 'returns a fallback for videos with no title' do
@mock_http.should_receive(:get).with(@api_path, nil).and_return(
[nil, "Foobar #{@expected_title} hallo welt dsd"])
youtube_title_for(@video_id).should == I18n.t('application.helper.video_title.unknown')
end
end
+
describe 'serialization and marshalling' do
before do
@expected_title = '""Procrastination"" Tales Of Mere Existence'
@@ -33,10 +39,34 @@ describe YoutubeTitles do
[nil, "Foobar #{@expected_title} hallo welt dsd"])
@post = Factory.create(:status_message, :text => @url)
end
+
it 'can be re-marshalled' do
lambda {
StatusMessage.find(@post.id).youtube_titles
}.should_not raise_error
end
end
+
+ describe "YOUTUBE_ID_REGEX" do
+ specify "normal url" do
+ url = "http://www.youtube.com/watch?v=dQw4w9WgXcQ"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+
+ specify "https url" do
+ url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+
+ specify "url with extra query params" do
+ url = "http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=related"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+ end
end
diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb
index 344f99946..40c062067 100644
--- a/spec/mailers/notifier_spec.rb
+++ b/spec/mailers/notifier_spec.rb
@@ -83,11 +83,11 @@ describe Notifier do
end
it 'has the receivers name in the body' do
- @mail.body.encoded.include?(@user.person.profile.first_name).should be true
+ @mail.body.encoded.include?(@user.person.profile.first_name).should be_true
end
it 'has the name of person mentioning in the body' do
- @mail.body.encoded.include?(@sm.author.name).should be true
+ @mail.body.encoded.include?(@sm.author.name).should be_true
end
it 'has the post text in the body' do
@@ -99,6 +99,30 @@ describe Notifier do
end
end
+ describe ".liked" do
+ before do
+ @sm = Factory(:status_message, :author => alice.person)
+ @like = @sm.likes.create(:author => bob.person)
+ @mail = Notifier.liked(alice.id, @like.author.id, @like.id)
+ end
+
+ it 'goes to the right person' do
+ @mail.to.should == [alice.email]
+ end
+
+ it 'has the receivers name in the body' do
+ @mail.body.encoded.include?(alice.person.profile.first_name).should be true
+ end
+
+ it 'has the name of person liking in the body' do
+ @mail.body.encoded.include?(@like.author.name).should be_true
+ end
+
+ it 'should not include translation missing' do
+ @mail.body.encoded.should_not include("missing")
+ end
+ end
+
describe ".private_message" do
before do
@user2 = bob
@@ -135,6 +159,7 @@ describe Notifier do
@mail.body.encoded.should_not include("missing")
end
end
+
context "comments" do
let!(:connect) { connect_users(user, aspect, user2, aspect2)}
let!(:sm) {user.post(:status_message, :text => "Sunny outside", :to => :all)}
diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb
index bf754590a..f844c2ab7 100644
--- a/spec/models/comment_spec.rb
+++ b/spec/models/comment_spec.rb
@@ -92,20 +92,22 @@ describe Comment do
before do
@message = alice.post :status_message, :text => "hi", :to => @alices_aspect.id
end
+
it 'should process youtube titles on the way in' do
- video_id = "ABYnqp-bxvg"
- url="http://www.youtube.com/watch?v=#{video_id}&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
- expected_title = "UP & down & UP & down &"
+ first_video_id = "ABYnqp-1111"
+ second_video_id = "ABYnqp-2222"
+ url = "http://www.youtube.com/watch?v=#{first_video_id} http://www.youtube.com/watch?v=#{second_video_id}"
+ expected_title = "UP & down & UP & down &"
mock_http = mock("http")
- Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(mock_http)
- mock_http.should_receive(:get).with('/feeds/api/videos/'+video_id+'?v=2', nil).and_return(
+ Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).twice.and_return(mock_http)
+ mock_http.should_receive(:get).with(/\/feeds\/api\/videos/, nil).twice.and_return(
[nil, 'Foobar '+expected_title+' hallo welt dsd'])
comment = alice.build_comment url, :on => @message
-
comment.save!
- Comment.find(comment.id).youtube_titles.should == {video_id => CGI::escape(expected_title)}
+
+ Comment.find(comment.id).youtube_titles.should == { first_video_id => CGI::escape(expected_title), second_video_id => CGI::escape(expected_title) }
end
end
diff --git a/spec/models/like_spec.rb b/spec/models/like_spec.rb
index 9fea70324..8bdc4ca25 100644
--- a/spec/models/like_spec.rb
+++ b/spec/models/like_spec.rb
@@ -12,7 +12,7 @@ describe Like do
@bob = bob
@eve = eve
- @status = alice.post(:status_message, :text => "hello", :to => @alices_aspect.id)
+ @status = bob.post(:status_message, :text => "hello", :to => @alices_aspect.id)
end
describe 'User#like' do
@@ -34,6 +34,24 @@ describe Like do
end
end
+ describe '#notification_type' do
+ before do
+ @like = @alice.like(1, :on => @status)
+ end
+
+ it 'should be notifications liked if you are the post owner' do
+ @like.notification_type(@bob, @alice.person).should be Notifications::Liked
+ end
+
+ it 'should not notify you if you are the like-r' do
+ @like.notification_type(@alice, @alice.person).should be_nil
+ end
+
+ it 'should not notify you if you did not create the post' do
+ @like.notification_type(@eve, @alice.person).should be_nil
+ end
+ end
+
describe 'xml' do
before do
@liker = Factory.create(:user)
@@ -67,11 +85,11 @@ describe Like do
@local_luke, @local_leia, @remote_raphael = set_up_friends
@remote_parent = Factory.create(:status_message, :author => @remote_raphael)
@local_parent = @local_luke.post :status_message, :text => "foobar", :to => @local_luke.aspects.first
-
+
@object_by_parent_author = @local_luke.like(1, :on => @local_parent)
@object_by_recipient = @local_leia.build_like(1, :on => @local_parent)
@dup_object_by_parent_author = @object_by_parent_author.dup
-
+
@object_on_remote_parent = @local_luke.like(0, :on => @remote_parent)
end
it_should_behave_like 'it is relayable'
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 7d093669d..a617782e2 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -40,6 +40,10 @@ RSpec.configure do |config|
$process_queue = false
end
+
+ config.before(:each, :type => :controller) do
+ self.class.render_views
+ end
end
disable_typhoeus
Evil"
+ person_link(@person).should_not include("")
end
end
end
diff --git a/spec/helpers/layout_helper_spec.rb b/spec/helpers/layout_helper_spec.rb
new file mode 100644
index 000000000..3bf5c1359
--- /dev/null
+++ b/spec/helpers/layout_helper_spec.rb
@@ -0,0 +1,38 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe LayoutHelper do
+ before do
+ @user = alice
+ end
+
+ describe "#page_title" do
+ before do
+ def current_user
+ @current_user
+ end
+ end
+
+ context "passed blank text" do
+ it "returns current_user.name if logged in" do
+ @current_user = @user
+ page_title.should == @user.name
+ end
+
+ it "returns default title if not logged in" do
+ @current_user = nil
+ page_title.should == I18n.t("application.helper.diaspora_alpha")
+ end
+ end
+
+ context "passed text" do
+ it "returns the text" do
+ text = "This is the title"
+ page_title(text).should == text
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/helpers/markdownify_helper_spec.rb b/spec/helpers/markdownify_helper_spec.rb
new file mode 100644
index 000000000..e292490d4
--- /dev/null
+++ b/spec/helpers/markdownify_helper_spec.rb
@@ -0,0 +1,239 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe MarkdownifyHelper do
+ describe "#markdownify" do
+ describe "autolinks" do
+ it "should not allow basic XSS/HTML" do
+ markdownify("").should == "<script>alert('XSS is evil')</script>"
+ end
+
+ it "should recognize basic http links (1/3)" do
+ proto="http"
+ url="bugs.joindiaspora.com/issues/332"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize basic http links (2/3)" do
+ proto="http"
+ url="webmail.example.com?~()!*/"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize basic http links (3/3)" do
+ proto="http"
+ url="127.0.0.1:3000/users/sign_in"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ it "should recognize secure https links" do
+ proto="https"
+ url="127.0.0.1:3000/users/sign_in"
+ markdownify(proto+"://"+url).should == ""+url+""
+ end
+
+ describe "video links" do
+ it "recognizes vimeo links" do
+ video_id = "17449557"
+ url = "http://www.vimeo.com/#{video_id}"
+ res = markdownify(url)
+ res.should =~ /data-host="vimeo.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "recognizes youtube links" do
+ video_id = "0x__dDWdf23"
+ url = "http://www.youtube.com/watch?v=" + video_id + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "recognizes youtube links with hyphens" do
+ video_id = "ABYnqp-bxvg"
+ url = "http://www.youtube.com/watch?v=" + video_id + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ end
+
+ it "keeps anchors" do
+ anchor = "#t=11m34"
+ video_id = "DHRoHuv3I8E"
+ url = "http://www.youtube.com/watch?v=" + video_id + anchor
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ res.should =~ /data-anchor="#{anchor}"/
+ end
+
+ it "has an empty data-anchor attribute if there is no anchor" do
+ video_id = "DHRoHuv3I8E"
+ url = "http://www.youtube.com/watch?v=" + video_id
+ res = markdownify(url)
+ res.should =~ /Youtube:/
+ res.should =~ /data-host="youtube.com"/
+ res.should =~ /data-video-id="#{video_id}"/
+ res.should =~ /data-anchor=""/
+ end
+
+ it "leaves the links in the href of the #a tag" do
+ video_id = "ABYnqp-bxvg"
+ start_url ="http://www.youtube.com/watch?v=" + video_id
+ url = start_url + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.should =~ /href=[\S]+v=#{video_id}/
+ end
+
+ it 'does not autolink inside the link' do
+ video_id = "ABYnqp-bxvg"
+ start_url ="http://www.youtube.com/watch?v=" + video_id
+ url = start_url + "&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+ res = markdownify(url)
+ res.match(/href=""+url+""
+ end
+
+ it "should recognize www links" do
+ url="www.joindiaspora.com"
+ markdownify(url).should == ""+url+""
+ end
+ end
+
+ describe "emoticons" do
+ it "replaces <3 with ♥" do
+ message = "i <3 you"
+ markdownify(message).should == "i ♥ you"
+ end
+
+ it "replaces various things with (their) HTML entities" do
+ message = ":) :-) :( :-( ... -> <- (tm) (r) (c)"
+ markdownify(message).should == "☺ ☺ ☹ ☹ … → ← ™ ® ©"
+ end
+
+ it "skips doing it if you say so" do
+ message = ":) :-) :( :-( ... -> <-"
+ markdownify(message, :emoticons => false).should == ":) :-) :( :-( ... -> <-"
+ end
+ end
+
+ describe "weak emphasis" do
+ it "should be recognized (1/2)" do
+ message = "*some text* some text *some text* some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+
+ it "should be recognized (2/2)" do
+ message = "_some text_ some text _some text_ some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+ end
+
+ describe "strong emphasis" do
+ it "should be recognized (1/2)" do
+ message = "**some text** some text **some text** some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+
+ it "should be recognized (2/2)" do
+ message = "__some text__ some text __some text__ some text"
+ markdownify(message).should == "some text some text some text some text"
+ end
+ end
+
+ describe "nested weak and strong emphasis" do
+ it "should be rendered correctly" do
+ message = "__this is _some_ text__"
+ markdownify(message).should == "this is some text"
+ message = "*this is **some** text*"
+ markdownify(message).should == "this is some text"
+ message = "___some text___"
+ markdownify(message).should == "some text"
+ end
+ end
+
+ describe "links" do
+ it "should be recognized without title attribute" do
+ message = "[link text](http://someurl.com) [link text](http://someurl.com)"
+ markdownify(message).should == 'link text link text'
+ end
+
+ it "should be recognized with title attribute" do
+ message = '[link text](http://someurl.com "some title") [link text](http://someurl.com "some title")'
+ markdownify(message).should == 'link text link text'
+ end
+
+ it "should have a robust link parsing" do
+ message = "This [*text*](http://en.wikipedia.org/wiki/Text_(literary_theory)) with many [links](google.com) tests [_http_](http://google.com/search?q=with_multiple__underscores*and**asterisks), [___FTP___](ftp://ftp.uni-kl.de/CCC/26C3/mp4/26c3-3540-en-a_hackers_utopia.mp4 \"File Transfer Protocol\"), [**any protocol**](foo://bar.example.org/yes_it*makes*no_sense)"
+ markdownify(message).should == 'This text with many links tests http, FTP, any protocol'
+ end
+ end
+
+ describe "nested emphasis and links tags" do
+ it "should be rendered correctly" do
+ message = '[**some *link* text**](someurl.com "some title")'
+ markdownify(message).should == 'some link text'
+ end
+ end
+
+ it "should allow escaping" do
+ message = '*some text* \\*some text* \\**some text* _some text_ \\_some text_ \\__some text_'
+ markdownify(message).should == "some text *some text **some text some text _some text __some text"
+ end
+
+ describe "newlines" do
+ it 'skips inserting newlines if you pass the newlines option' do
+ message = "These\nare\n\some\nnew\lines"
+ res = markdownify(message, :newlines => false)
+ res.should == message
+ end
+
+ it 'generates breaklines' do
+ message = "These\nare\nsome\nnew\nlines"
+ res = markdownify(message)
+ res.should == "These
are
some
new
lines"
+ end
+
+ it 'should render newlines and basic http links correctly' do
+ message = "Some text, then a line break and a link\nhttp://joindiaspora.com\nsome more text"
+ res = markdownify(message)
+ res.should == 'Some text, then a line break and a link
joindiaspora.com
some more text'
+ end
+ end
+
+ context 'performance' do
+ before do
+ @message = "HHello,Hello_, I _am a strong robot.*Hello, I am *a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a **strong robot.Hello, I am _a _strong *robot**.Hello*, I am a strong "
+ end
+
+ it 'is sub millisecond' do
+ Benchmark.realtime{
+ markdownify(@message)
+ }.should < 0.001
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/helpers/stream_helper_spec.rb b/spec/helpers/stream_helper_spec.rb
new file mode 100644
index 000000000..ebb6ce0b7
--- /dev/null
+++ b/spec/helpers/stream_helper_spec.rb
@@ -0,0 +1,24 @@
+# Copyright (c) 2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe StreamHelper do
+ before do
+ @post = Factory(:status_message)
+ end
+ describe "#time_for_sort" do
+ it "returns sort_order for an aspectscontroller" do
+ sort_order = :stored_in_session
+ stub!(:controller).and_return(AspectsController.new)
+ stub!(:session).and_return({:sort_order => sort_order})
+ @post.should_receive(sort_order)
+ time_for_sort(@post)
+ end
+ it "returns post.created_at otherwise" do
+ stub!(:controller).and_return(mock())
+ time_for_sort(@post).should == @post.created_at
+ end
+ end
+end
diff --git a/spec/javascripts/content-updater-spec.js b/spec/javascripts/content-updater-spec.js
new file mode 100644
index 000000000..df0bc5ae0
--- /dev/null
+++ b/spec/javascripts/content-updater-spec.js
@@ -0,0 +1,34 @@
+/* Copyright (c) 2010, Diaspora Inc. This file is
+* licensed under the Affero General Public License version 3 or later. See
+* the COPYRIGHT file.
+*/
+
+describe("ContentUpdater", function() {
+ describe("addPostToStream", function() {
+
+ beforeEach(function() {
+ $("#jasmine_content").empty();
+ spec.loadFixture("aspects_index");
+ });
+
+ it("adds a post to the stream", function() {
+ var originalPostCount = $(".stream_element").length;
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ });
+
+ it("does not add duplicate posts", function() {
+ var originalPostCount = $(".stream_element").length;
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($(".stream_element").length).toEqual(originalPostCount + 1);
+ });
+
+ it("removes the div that says you have no posts if it exists", function() {
+ expect($("#no_posts").length).toEqual(1);
+ ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream"));
+ expect($("#no_posts").length).toEqual(0);
+ });
+ });
+});
diff --git a/spec/javascripts/stream-spec.js b/spec/javascripts/stream-spec.js
index 19b6e71e6..4b0a16275 100644
--- a/spec/javascripts/stream-spec.js
+++ b/spec/javascripts/stream-spec.js
@@ -6,31 +6,7 @@
describe("Stream", function() {
beforeEach(function() {
jasmine.Clock.useMock();
- $('#jasmine_content').html(
- '' +
- '' +
- '' +
- '' +
- 'show comments (0)' +
- '' +
- '' +
- '' +
- ' ' +
- ''
- );
+ spec.loadFixture('aspects_index_with_posts');
});
describe("initialize", function() {
@@ -48,16 +24,17 @@ describe("Stream", function() {
Stream.initialize();
});
it("toggles class hidden on the comment block", function () {
- expect(jQuery('ul.comments')).toHaveClass("hidden");
+ expect(jQuery('ul.comments')).not.toHaveClass("hidden");
$("a.show_post_comments").click();
jasmine.Clock.tick(200);
- expect(jQuery('ul.comments')).not.toHaveClass("hidden");
+ expect(jQuery('ul.comments')).toHaveClass("hidden");
});
it("changes the text on the show comments link", function() {
+ expect($("a.show_post_comments").text()).toEqual("hide comments (1)");
$("a.show_post_comments").click();
jasmine.Clock.tick(200);
- expect($("a.show_post_comments").text()).toEqual("hide comments (0)");
+ expect($("a.show_post_comments").text()).toEqual("show comments (1)");
});
});
});
diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml
index de698e936..707fb41ad 100644
--- a/spec/javascripts/support/jasmine.yml
+++ b/spec/javascripts/support/jasmine.yml
@@ -30,6 +30,7 @@ src_files:
- public/javascripts/widgets/directionDetector.js
- public/javascripts/widgets/infinite-scroll.js
- public/javascripts/widgets/notifications.js
+ - public/javascripts/widgets/flashes.js
- public/javascripts/mobile.js
- public/javascripts/contact-list.js
- public/javascripts/web-socket-receiver.js
@@ -39,6 +40,7 @@ src_files:
- public/javascripts/validation.js
- public/javascripts/rails.js
- public/javascripts/aspect-filters.js
+ - public/javascripts/content-updater.js
# stylesheets
#
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
diff --git a/spec/javascripts/view-spec.js b/spec/javascripts/view-spec.js
index ba3a3600f..a2e9eefbe 100644
--- a/spec/javascripts/view-spec.js
+++ b/spec/javascripts/view-spec.js
@@ -42,33 +42,6 @@ describe("View", function() {
});
});
- describe("flashes", function() {
- describe("animate", function() {
- beforeEach(function() {
- $("#jasmine_content").html(
- '' +
- 'flash! flash! flash!' +
- ''
- );
- });
-
- it("is called when the DOM is ready", function() {
- spyOn(View.flashes, "animate").andCallThrough();
- View.initialize();
- expect(View.flashes.animate).toHaveBeenCalled();
- });
- });
- describe("render", function() {
- it("creates a new div and calls flashes.animate", function() {
- spyOn(View.flashes, "animate");
- View.flashes.render({
- success: true,
- message: "success!"
- });
- expect(View.flashes.animate).toHaveBeenCalled();
- });
- });
- });
describe("newRequest", function() {
beforeEach(function() {
diff --git a/spec/javascripts/widgets/flashes-spec.js b/spec/javascripts/widgets/flashes-spec.js
new file mode 100644
index 000000000..1ac7061e9
--- /dev/null
+++ b/spec/javascripts/widgets/flashes-spec.js
@@ -0,0 +1,32 @@
+describe("Diaspora", function() {
+ describe("widgets", function() {
+ describe("flashes", function() {
+ describe("animateMessages", function() {
+ beforeEach(function() {
+ $("#jasmine_content").html(
+ '' +
+ 'flash message' +
+ ''
+ );
+ });
+
+ it("is called when the DOM is ready", function() {
+ spyOn(Diaspora.widgets.flashes, "animateMessages").andCallThrough();
+ Diaspora.widgets.flashes.start();
+ expect(Diaspora.widgets.flashes.animateMessages).toHaveBeenCalled();
+ });
+ });
+
+ describe("render", function() {
+ it("creates a new div for the message and calls flashes.animateMessages", function() {
+ spyOn(Diaspora.widgets.flashes, "animateMessages");
+ Diaspora.widgets.flashes.render({
+ success: true,
+ message: "success!"
+ });
+ expect(Diaspora.widgets.flashes.animateMessages).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/spec/javascripts/widgets/notifications-spec.js b/spec/javascripts/widgets/notifications-spec.js
index aeedf1d57..c68854205 100644
--- a/spec/javascripts/widgets/notifications-spec.js
+++ b/spec/javascripts/widgets/notifications-spec.js
@@ -50,6 +50,18 @@ describe("Diaspora", function() {
expect($("#notifications div").length).toEqual(1);
});
+
+ it("only increments the notification count if specified to do so", function() {
+ var originalCount = Diaspora.widgets.notifications.count;
+
+ Diaspora.widgets.notifications.showNotification({
+ html: '',
+ incrementCount: false
+ });
+
+ expect(Diaspora.widgets.notifications.count).toEqual(originalCount);
+
+ });
});
});
});
diff --git a/spec/lib/youtube_titles_spec.rb b/spec/lib/youtube_titles_spec.rb
index d9c82a84f..82e6ec107 100644
--- a/spec/lib/youtube_titles_spec.rb
+++ b/spec/lib/youtube_titles_spec.rb
@@ -1,29 +1,35 @@
require 'spec_helper'
require 'youtube_titles'
+
describe YoutubeTitles do
+ include YoutubeTitles
+
before do
@video_id = "ABYnqp-bxvg"
@url="http://www.youtube.com/watch?v=#{@video_id}&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
@api_path = "/feeds/api/videos/#{@video_id}?v=2"
end
- include YoutubeTitles
+
describe '#youtube_title_for' do
before do
@expected_title = "UP & down & UP & down &"
@mock_http = mock("http")
Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(@mock_http)
end
+
it 'gets a youtube title corresponding to an id' do
@mock_http.should_receive(:get).with(@api_path, nil).and_return(
[nil, "Foobar #{@expected_title} hallo welt dsd"])
youtube_title_for(@video_id).should == @expected_title
end
+
it 'returns a fallback for videos with no title' do
@mock_http.should_receive(:get).with(@api_path, nil).and_return(
[nil, "Foobar #{@expected_title} hallo welt dsd"])
youtube_title_for(@video_id).should == I18n.t('application.helper.video_title.unknown')
end
end
+
describe 'serialization and marshalling' do
before do
@expected_title = '""Procrastination"" Tales Of Mere Existence'
@@ -33,10 +39,34 @@ describe YoutubeTitles do
[nil, "Foobar #{@expected_title} hallo welt dsd"])
@post = Factory.create(:status_message, :text => @url)
end
+
it 'can be re-marshalled' do
lambda {
StatusMessage.find(@post.id).youtube_titles
}.should_not raise_error
end
end
+
+ describe "YOUTUBE_ID_REGEX" do
+ specify "normal url" do
+ url = "http://www.youtube.com/watch?v=dQw4w9WgXcQ"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+
+ specify "https url" do
+ url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+
+ specify "url with extra query params" do
+ url = "http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=related"
+ matched_data = url.match(YoutubeTitles::YOUTUBE_ID_REGEX)
+ matched_data[0].should == url
+ matched_data[1].should == "dQw4w9WgXcQ"
+ end
+ end
end
diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb
index 344f99946..40c062067 100644
--- a/spec/mailers/notifier_spec.rb
+++ b/spec/mailers/notifier_spec.rb
@@ -83,11 +83,11 @@ describe Notifier do
end
it 'has the receivers name in the body' do
- @mail.body.encoded.include?(@user.person.profile.first_name).should be true
+ @mail.body.encoded.include?(@user.person.profile.first_name).should be_true
end
it 'has the name of person mentioning in the body' do
- @mail.body.encoded.include?(@sm.author.name).should be true
+ @mail.body.encoded.include?(@sm.author.name).should be_true
end
it 'has the post text in the body' do
@@ -99,6 +99,30 @@ describe Notifier do
end
end
+ describe ".liked" do
+ before do
+ @sm = Factory(:status_message, :author => alice.person)
+ @like = @sm.likes.create(:author => bob.person)
+ @mail = Notifier.liked(alice.id, @like.author.id, @like.id)
+ end
+
+ it 'goes to the right person' do
+ @mail.to.should == [alice.email]
+ end
+
+ it 'has the receivers name in the body' do
+ @mail.body.encoded.include?(alice.person.profile.first_name).should be true
+ end
+
+ it 'has the name of person liking in the body' do
+ @mail.body.encoded.include?(@like.author.name).should be_true
+ end
+
+ it 'should not include translation missing' do
+ @mail.body.encoded.should_not include("missing")
+ end
+ end
+
describe ".private_message" do
before do
@user2 = bob
@@ -135,6 +159,7 @@ describe Notifier do
@mail.body.encoded.should_not include("missing")
end
end
+
context "comments" do
let!(:connect) { connect_users(user, aspect, user2, aspect2)}
let!(:sm) {user.post(:status_message, :text => "Sunny outside", :to => :all)}
diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb
index bf754590a..f844c2ab7 100644
--- a/spec/models/comment_spec.rb
+++ b/spec/models/comment_spec.rb
@@ -92,20 +92,22 @@ describe Comment do
before do
@message = alice.post :status_message, :text => "hi", :to => @alices_aspect.id
end
+
it 'should process youtube titles on the way in' do
- video_id = "ABYnqp-bxvg"
- url="http://www.youtube.com/watch?v=#{video_id}&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
- expected_title = "UP & down & UP & down &"
+ first_video_id = "ABYnqp-1111"
+ second_video_id = "ABYnqp-2222"
+ url = "http://www.youtube.com/watch?v=#{first_video_id} http://www.youtube.com/watch?v=#{second_video_id}"
+ expected_title = "UP & down & UP & down &"
mock_http = mock("http")
- Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(mock_http)
- mock_http.should_receive(:get).with('/feeds/api/videos/'+video_id+'?v=2', nil).and_return(
+ Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).twice.and_return(mock_http)
+ mock_http.should_receive(:get).with(/\/feeds\/api\/videos/, nil).twice.and_return(
[nil, 'Foobar '+expected_title+' hallo welt dsd'])
comment = alice.build_comment url, :on => @message
-
comment.save!
- Comment.find(comment.id).youtube_titles.should == {video_id => CGI::escape(expected_title)}
+
+ Comment.find(comment.id).youtube_titles.should == { first_video_id => CGI::escape(expected_title), second_video_id => CGI::escape(expected_title) }
end
end
diff --git a/spec/models/like_spec.rb b/spec/models/like_spec.rb
index 9fea70324..8bdc4ca25 100644
--- a/spec/models/like_spec.rb
+++ b/spec/models/like_spec.rb
@@ -12,7 +12,7 @@ describe Like do
@bob = bob
@eve = eve
- @status = alice.post(:status_message, :text => "hello", :to => @alices_aspect.id)
+ @status = bob.post(:status_message, :text => "hello", :to => @alices_aspect.id)
end
describe 'User#like' do
@@ -34,6 +34,24 @@ describe Like do
end
end
+ describe '#notification_type' do
+ before do
+ @like = @alice.like(1, :on => @status)
+ end
+
+ it 'should be notifications liked if you are the post owner' do
+ @like.notification_type(@bob, @alice.person).should be Notifications::Liked
+ end
+
+ it 'should not notify you if you are the like-r' do
+ @like.notification_type(@alice, @alice.person).should be_nil
+ end
+
+ it 'should not notify you if you did not create the post' do
+ @like.notification_type(@eve, @alice.person).should be_nil
+ end
+ end
+
describe 'xml' do
before do
@liker = Factory.create(:user)
@@ -67,11 +85,11 @@ describe Like do
@local_luke, @local_leia, @remote_raphael = set_up_friends
@remote_parent = Factory.create(:status_message, :author => @remote_raphael)
@local_parent = @local_luke.post :status_message, :text => "foobar", :to => @local_luke.aspects.first
-
+
@object_by_parent_author = @local_luke.like(1, :on => @local_parent)
@object_by_recipient = @local_leia.build_like(1, :on => @local_parent)
@dup_object_by_parent_author = @object_by_parent_author.dup
-
+
@object_on_remote_parent = @local_luke.like(0, :on => @remote_parent)
end
it_should_behave_like 'it is relayable'
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 7d093669d..a617782e2 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -40,6 +40,10 @@ RSpec.configure do |config|
$process_queue = false
end
+
+ config.before(:each, :type => :controller) do
+ self.class.render_views
+ end
end
disable_typhoeus
are
some
new
lines" + end + + it 'should render newlines and basic http links correctly' do + message = "Some text, then a line break and a link\nhttp://joindiaspora.com\nsome more text" + res = markdownify(message) + res.should == 'Some text, then a line break and a link
joindiaspora.com
some more text' + end + end + + context 'performance' do + before do + @message = "HHello,Hello_, I _am a strong robot.*Hello, I am *a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a strong robot.Hello, I am a **strong robot.Hello, I am _a _strong *robot**.Hello*, I am a strong " + end + + it 'is sub millisecond' do + Benchmark.realtime{ + markdownify(@message) + }.should < 0.001 + end + end + end +end \ No newline at end of file diff --git a/spec/helpers/stream_helper_spec.rb b/spec/helpers/stream_helper_spec.rb new file mode 100644 index 000000000..ebb6ce0b7 --- /dev/null +++ b/spec/helpers/stream_helper_spec.rb @@ -0,0 +1,24 @@ +# Copyright (c) 2011, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +require 'spec_helper' + +describe StreamHelper do + before do + @post = Factory(:status_message) + end + describe "#time_for_sort" do + it "returns sort_order for an aspectscontroller" do + sort_order = :stored_in_session + stub!(:controller).and_return(AspectsController.new) + stub!(:session).and_return({:sort_order => sort_order}) + @post.should_receive(sort_order) + time_for_sort(@post) + end + it "returns post.created_at otherwise" do + stub!(:controller).and_return(mock()) + time_for_sort(@post).should == @post.created_at + end + end +end diff --git a/spec/javascripts/content-updater-spec.js b/spec/javascripts/content-updater-spec.js new file mode 100644 index 000000000..df0bc5ae0 --- /dev/null +++ b/spec/javascripts/content-updater-spec.js @@ -0,0 +1,34 @@ +/* Copyright (c) 2010, Diaspora Inc. This file is +* licensed under the Affero General Public License version 3 or later. See +* the COPYRIGHT file. +*/ + +describe("ContentUpdater", function() { + describe("addPostToStream", function() { + + beforeEach(function() { + $("#jasmine_content").empty(); + spec.loadFixture("aspects_index"); + }); + + it("adds a post to the stream", function() { + var originalPostCount = $(".stream_element").length; + ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream")); + expect($(".stream_element").length).toEqual(originalPostCount + 1); + }); + + it("does not add duplicate posts", function() { + var originalPostCount = $(".stream_element").length; + ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream")); + expect($(".stream_element").length).toEqual(originalPostCount + 1); + ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream")); + expect($(".stream_element").length).toEqual(originalPostCount + 1); + }); + + it("removes the div that says you have no posts if it exists", function() { + expect($("#no_posts").length).toEqual(1); + ContentUpdater.addPostToStream(spec.fixtureHtml("status_message_in_stream")); + expect($("#no_posts").length).toEqual(0); + }); + }); +}); diff --git a/spec/javascripts/stream-spec.js b/spec/javascripts/stream-spec.js index 19b6e71e6..4b0a16275 100644 --- a/spec/javascripts/stream-spec.js +++ b/spec/javascripts/stream-spec.js @@ -6,31 +6,7 @@ describe("Stream", function() { beforeEach(function() { jasmine.Clock.useMock(); - $('#jasmine_content').html( - '