diff --git a/app/views/publisher/_publisher.html.haml b/app/views/publisher/_publisher.html.haml
index 3ecec1f40..4d85b0290 100644
--- a/app/views/publisher/_publisher.html.haml
+++ b/app/views/publisher/_publisher.html.haml
@@ -26,11 +26,11 @@
%input.typeahead-mention-box.hidden{type: "text"}
= status.hidden_field :text, value: h(publisher_hidden_text), class: "clear_on_submit"
- .container-fluid#photodropzone_container
+ .container-fluid.photodropzone-container#photodropzone_container
%ul#photodropzone
.location-container.form-group{style: "padding: 4px 6px;"}
= hidden_field :location, :coords
- #poll_creator_container
+ .poll-creator-container#poll_creator_container
-# handlebars template
#button_container
.publisher-buttonbar#publisher-images
@@ -59,12 +59,8 @@
.spinner
.options_and_submit.col-sm-12
.public_toggle.clearfix
- .btn.btn-default.pull-left.hidden-xs#hide_publisher{title: t("shared.publisher.discard_post")}
- %span.text= t("cancel")
-
.btn-toolbar.pull-right
= render partial: "publisher/aspect_dropdown", locals: {selected_aspects: selected_aspects}
- %button.btn.btn-default.btn-group.post_preview_button= t("shared.publisher.preview")
%button.btn.btn-group.btn-primary#submit= t("shared.publisher.share")
.btn-toolbar.pull-right#publisher-service-icons
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index 9f3f8cd92..686871f66 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -2,6 +2,13 @@
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
+# bootstrap-markdown plugin relies on rails-assets-bootstrap gem but we use
+# bootstrap-sass this line makes sure we exclude every asset comming
+# from rails-assets-bootstrap to prevent conflicts with bootstrap-sass
+Rails.configuration.assets.paths.reject! do |path|
+ path.include?("rails-assets-bootstrap") && !path.include?("rails-assets-bootstrap-markdown")
+end
+
Diaspora::Application.configure do
config.serve_static_files = AppConfig.environment.assets.serve?
# config.static_cache_control = "public, max-age=3600" if AppConfig[:serve_static_assets].to_s == 'true'
diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml
index b961cbf91..99419cc2d 100644
--- a/config/locales/diaspora/en.yml
+++ b/config/locales/diaspora/en.yml
@@ -1031,7 +1031,6 @@ en:
formatWithMarkdown: "You can use %{markdown_link} to format your post"
posting: "Posting..."
share: "Share"
- preview: "Preview"
upload_photos: "Upload photos"
get_location: "Get your location"
remove_location: "Remove location"
diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml
index 7066e750b..0d31f9178 100644
--- a/config/locales/javascript/javascript.en.yml
+++ b/config/locales/javascript/javascript.en.yml
@@ -138,6 +138,35 @@ en:
option: "Answer"
add_option: "Add an answer"
question: "Question"
+ markdown_editor:
+ preview: "Preview"
+ write: "Write"
+ tooltips:
+ bold: "Bold"
+ italic: "Italic"
+ heading: "Heading"
+ insert_link: "Insert link"
+ insert_image: "Insert image"
+ insert_ordered_list: "Insert ordered list"
+ insert_unordered_list: "Insert unordered list"
+ preview: "Preview message"
+ write: "Edit message"
+ cancel: "Cancel message"
+ quote: "Insert quotation"
+ code: "Insert code"
+ texts:
+ strong: "strong text"
+ italic: "italic text"
+ heading: "heading text"
+ insert_link_description_text: "enter link description here"
+ insert_link_help_text: "Insert link here"
+ insert_image_description_text: "enter image description here"
+ insert_image_help_text: "Insert image link here"
+ insert_image_title: "enter image title here"
+ list: "list text here"
+ quote: "quotation text here"
+ code: "code here"
+
bookmarklet:
post_something: "Post to diaspora*"
post_submit: "Submitting post..."
diff --git a/features/desktop/post_preview.feature b/features/desktop/post_preview.feature
index 15c89c540..20e785471 100644
--- a/features/desktop/post_preview.feature
+++ b/features/desktop/post_preview.feature
@@ -16,26 +16,27 @@ Feature: preview posts in the stream
Scenario: preview and post a text-only message
Given I expand the publisher
When I write the status message "I am eating yogurt"
- And I press "Preview"
- Then "I am eating yogurt" should be post 1
- And the first post should be a preview
+ And I preview the post
+ Then I should see "I am eating yogurt" in the preview
+ Given I edit the post
When I write the status message "This preview rocks"
- And I press "Preview"
- Then "This preview rocks" should be post 1
- And I should not see "I am eating a yogurt"
+ And I preview the post
+ Then I should see "This preview rocks" in the preview
+ And I should not see "I am eating a yogurt" in the preview
+ Given I edit the post
When I write the status message "I like rocks"
And I press "Share"
Then "I like rocks" should be post 1
- And I should not see "This preview rocks"
+ When I expand the publisher
+ Then I should not be in preview mode
Scenario: preview a very long message
Given I expand the publisher
When I insert an extremely long status message
- And I press "Preview"
+ And I preview the post
Then the preview should not be collapsed
-
When I press "Share"
Then the post should be collapsed
@@ -44,15 +45,15 @@ Feature: preview posts in the stream
And I attach "spec/fixtures/button.png" to the publisher
When I fill in the following:
| status_message_fake_text | Look at this dog |
- And I press "Preview"
- Then I should see a "img" within ".stream_element div.photo_attachments"
- And I should see "Look at this dog" within ".stream_element"
+ And I preview the post
+ Then I should see a "img" within ".md-preview .stream_element .photo_attachments"
+ And I should see "Look at this dog" within ".md-preview .stream_element"
And I close the publisher
Scenario: preview a post with mentions
Given I expand the publisher
And I mention Alice in the publisher
- And I press "Preview"
+ And I preview the post
And I confirm the alert after I follow "Alice Smith"
Then I should see "Alice Smith"
@@ -63,9 +64,8 @@ Feature: preview posts in the stream
When I expand the publisher
And I fill in the following:
| status_message_fake_text | This preview rocks |
- And I press "Preview"
- Then "This preview rocks" should be post 1
- And the first post should be a preview
+ And I preview the post
+ Then I should see "This preview rocks" in the preview
And I close the publisher
Scenario: preview a post with the poll
@@ -79,9 +79,9 @@ Feature: preview posts in the stream
And I fill in the following for the options:
| normal |
| not normal |
- And I press "Preview"
- Then I should see a ".poll_form" within ".stream_element"
- And I should see a "form" within ".stream_element"
+ And I preview the post
+ Then I should see a ".poll_form" within ".md-preview .stream_element"
+ And I should see a "form" within ".md-preview .stream_element"
And I close the publisher
Scenario: preview a post with location
@@ -93,7 +93,7 @@ Feature: preview posts in the stream
When I fill in the following:
| status_message_fake_text | I am eating yogurt |
| location_address | Some cool place |
- And I press "Preview"
- Then I should see a ".near-from" within ".stream_element"
- And I should see "Some cool place" within ".stream_element .near-from"
+ And I preview the post
+ Then I should see a ".near-from" within ".md-preview .stream_element"
+ And I should see "Some cool place" within ".md-preview .stream_element .near-from"
And I close the publisher
diff --git a/features/desktop/posts_from_main_page.feature b/features/desktop/posts_from_main_page.feature
index 1c51665da..465bf8c0e 100644
--- a/features/desktop/posts_from_main_page.feature
+++ b/features/desktop/posts_from_main_page.feature
@@ -24,7 +24,8 @@ Feature: posting from the main page
When I expand the publisher
Then I should see "You can use Markdown to format your post" within ".markdownIndications"
Then I should see "All aspects" within ".options_and_submit"
- Then I should see "Preview" within ".options_and_submit"
+ Then I should see a ".md-write-tab" within ".md-header"
+ Then I should see a ".md-preview-tab" within ".md-header"
Scenario: post a text-only message to all aspects
Given I expand the publisher
diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb
index d8a0f9c79..73e9db02e 100644
--- a/features/step_definitions/custom_web_steps.rb
+++ b/features/step_definitions/custom_web_steps.rb
@@ -65,7 +65,7 @@ And /^I expand the publisher$/ do
end
And /^I close the publisher$/ do
- find("#publisher #hide_publisher").click
+ find("#publisher .md-cancel").click
end
Then /^the publisher should be expanded$/ do
diff --git a/features/step_definitions/post_preview_steps.rb b/features/step_definitions/post_preview_steps.rb
index 015400e15..f79b4e32e 100644
--- a/features/step_definitions/post_preview_steps.rb
+++ b/features/step_definitions/post_preview_steps.rb
@@ -1,9 +1,35 @@
-Then /^the first post should be a preview$/ do
- find(".post_preview .post-content").text.should == first_post_text
+And /^I edit the post$/ do
+ with_scope(".publisher-textarea-wrapper") do
+ find(".md-write-tab").click
+ end
end
Then /^the preview should not be collapsed$/ do
- find(".post_preview").should_not have_selector('.collapsed')
- find(".post_preview").should have_selector('.opened')
+ with_scope(".publisher-textarea-wrapper .collapsible") do
+ expect(current_scope).not_to have_css(".collapsed")
+ end
end
+And /^I preview the post$/ do
+ with_scope(".publisher-textarea-wrapper") do
+ find(".md-preview-tab").click
+ end
+end
+
+Then /^I should see "([^"]*)" in the preview$/ do |text|
+ with_scope(".publisher-textarea-wrapper .md-preview") do
+ expect(current_scope).to have_content(text)
+ end
+end
+
+Then /^I should not see "([^"]*)" in the preview$/ do |text|
+ with_scope(".publisher-textarea-wrapper .md-preview") do
+ expect(current_scope).to_not have_content(text)
+ end
+end
+
+Then /^I should not be in preview mode$/ do
+ with_scope(".publisher-textarea-wrapper") do
+ expect(current_scope).to_not have_css(".md-preview")
+ end
+end
diff --git a/features/support/publishing_cuke_helpers.rb b/features/support/publishing_cuke_helpers.rb
index 88c57d685..395318211 100644
--- a/features/support/publishing_cuke_helpers.rb
+++ b/features/support/publishing_cuke_helpers.rb
@@ -45,10 +45,8 @@ module PublishingCukeHelpers
end
def click_publisher
- page.execute_script('
- $("#publisher").removeClass("closed");
- $("#publisher").find("#status_message_fake_text").focus();
- ')
+ find("#status_message_fake_text").click
+ expect(find("#publisher")).to have_css(".publisher-textarea-wrapper.active")
end
def publisher_submittable?
diff --git a/spec/javascripts/app/views/preview_post_view_spec.js b/spec/javascripts/app/views/preview_post_view_spec.js
new file mode 100644
index 000000000..e2c1b5aec
--- /dev/null
+++ b/spec/javascripts/app/views/preview_post_view_spec.js
@@ -0,0 +1,81 @@
+describe("app.views.PreviewPost", function() {
+ beforeEach(function() {
+ this.model = new app.models.Post(factory.postAttrs());
+ this.view = new app.views.PreviewPost({model: this.model});
+ });
+
+ describe("initialize", function() {
+ it("sets preview property in model", function() {
+ this.view.initialize();
+ expect(this.view.model.get("preview")).toBe(true);
+ });
+
+ it("calls app.views.OEmbed.initialize", function() {
+ spyOn(app.views.OEmbed.prototype, "initialize");
+ this.view.initialize();
+ expect(app.views.OEmbed.prototype.initialize).toHaveBeenCalledWith({model: this.model});
+ });
+
+ it("calls app.views.OpenGraph.initialize", function() {
+ spyOn(app.views.OpenGraph.prototype, "initialize");
+ this.view.initialize();
+ expect(app.views.OpenGraph.prototype.initialize).toHaveBeenCalledWith({model: this.model});
+ });
+
+ it("calls app.views.Poll.initialize", function() {
+ spyOn(app.views.Poll.prototype, "initialize");
+ this.view.initialize();
+ expect(app.views.Poll.prototype.initialize).toHaveBeenCalledWith({model: this.model});
+ });
+
+ it("calls app.views.Poll.initialize", function() {
+ spyOn(app.views.Poll.prototype, "initialize");
+ this.view.initialize();
+ expect(app.views.Poll.prototype.initialize).toHaveBeenCalledWith({model: this.model});
+ });
+ });
+
+ describe("render", function() {
+ it("calls feedbackView", function() {
+ spyOn(app.views.PreviewPost.prototype, "feedbackView");
+ this.view.render();
+ expect(app.views.PreviewPost.prototype.feedbackView).toHaveBeenCalled();
+ });
+
+ it("calls postContentView", function() {
+ spyOn(app.views.PreviewPost.prototype, "postContentView");
+ this.view.render();
+ expect(app.views.PreviewPost.prototype.postContentView).toHaveBeenCalled();
+ });
+
+ it("calls postLocationStreamView", function() {
+ spyOn(app.views.PreviewPost.prototype, "postLocationStreamView");
+ this.view.render();
+ expect(app.views.PreviewPost.prototype.postLocationStreamView).toHaveBeenCalled();
+ });
+ });
+
+ describe("feedbackView", function() {
+ it("calls app.views.Feedback.initialise", function() {
+ spyOn(app.views.Feedback.prototype, "initialize");
+ this.view.feedbackView();
+ expect(app.views.Feedback.prototype.initialize).toHaveBeenCalledWith({model: this.model});
+ });
+ });
+
+ describe("postContentView", function() {
+ it("calls app.views.Feedback.initialise", function() {
+ spyOn(app.views.StatusMessage.prototype, "initialize");
+ this.view.postContentView();
+ expect(app.views.StatusMessage.prototype.initialize).toHaveBeenCalledWith({model: this.model});
+ });
+ });
+
+ describe("postLocationStreamView", function() {
+ it("calls app.views.Feedback.initialise", function() {
+ spyOn(app.views.LocationStream.prototype, "initialize");
+ this.view.postLocationStreamView();
+ expect(app.views.LocationStream.prototype.initialize).toHaveBeenCalledWith({model: this.model});
+ });
+ });
+});
diff --git a/spec/javascripts/app/views/publisher_view_spec.js b/spec/javascripts/app/views/publisher_view_spec.js
index fdf92826f..b80875f10 100644
--- a/spec/javascripts/app/views/publisher_view_spec.js
+++ b/spec/javascripts/app/views/publisher_view_spec.js
@@ -12,14 +12,11 @@ describe("app.views.Publisher", function() {
this.view = new app.views.Publisher({
standalone: true
});
+ this.view.open();
});
it("hides the close button in standalone mode", function() {
- expect(this.view.$("#hide_publisher").is(":visible")).toBeFalsy();
- });
-
- it("hides the post preview button in standalone mode", function() {
- expect(this.view.$(".post_preview_button").is(":visible")).toBeFalsy();
+ expect(this.view.$(".md-cancel").is(":visible")).toBeFalsy();
});
it("hides the manage services link in standalone mode", function() {
@@ -89,6 +86,21 @@ describe("app.views.Publisher", function() {
this.view.close($.Event());
expect($(this.view.el).find("#status_message_fake_text").attr("style")).not.toContain("height");
});
+
+ it("should hide the poll container correctly", function() {
+ this.view.$el.find(".poll-creator").click();
+ expect(this.view.$el.find(".publisher-textarea-wrapper")).toHaveClass("with-poll");
+ expect(this.view.$el.find(".poll-creator-container")).toBeVisible();
+ this.view.close();
+ expect(this.view.$el.find(".publisher-textarea-wrapper")).not.toHaveClass("with-poll");
+ expect(this.view.$el.find(".poll-creator-container")).not.toBeVisible();
+ this.view.open();
+ expect(this.view.$el.find(".publisher-textarea-wrapper")).not.toHaveClass("with-poll");
+ expect(this.view.$el.find(".poll-creator-container")).not.toBeVisible();
+ this.view.$el.find(".poll-creator").click();
+ expect(this.view.$el.find(".publisher-textarea-wrapper")).toHaveClass("with-poll");
+ expect(this.view.$el.find(".poll-creator-container")).toBeVisible();
+ });
});
describe("#clear", function() {
@@ -99,11 +111,11 @@ describe("app.views.Publisher", function() {
expect(this.view.close).toHaveBeenCalled();
});
- it("calls removePostPreview", function(){
- spyOn(this.view, "removePostPreview");
+ it("calls hidePreview", function() {
+ spyOn(this.view.markdownEditor, "hidePreview");
this.view.clear($.Event());
- expect(this.view.removePostPreview).toHaveBeenCalled();
+ expect(this.view.markdownEditor.hidePreview).toHaveBeenCalled();
});
it("clears all textareas", function(){
@@ -179,39 +191,11 @@ describe("app.views.Publisher", function() {
});
describe("createPostPreview", function(){
- beforeEach(function() {
- app.stream = { addNow: $.noop };
- });
-
it("calls handleTextchange to complete missing mentions", function(){
spyOn(this.view, "handleTextchange");
- this.view.createPostPreview($.Event());
+ this.view.createPostPreview();
expect(this.view.handleTextchange).toHaveBeenCalled();
});
-
- it("calls removePostPreview to remove the last preview", function(){
- spyOn(this.view, "removePostPreview");
- this.view.createPostPreview($.Event());
- expect(this.view.removePostPreview).toHaveBeenCalled();
- });
-
- it("adds the status message to the stream", function() {
- spyOn(app.stream, "addNow");
- this.view.createPostPreview($.Event());
- expect(app.stream.addNow).toHaveBeenCalled();
- });
-
- it("sets recentPreview", function(){
- expect(this.view.recentPreview).toBeUndefined();
- this.view.createPostPreview($.Event());
- expect(this.view.recentPreview).toBeDefined();
- });
-
- it("calls modifyPostPreview to apply the preview style to the post", function(){
- spyOn(this.view, "modifyPostPreview");
- this.view.createPostPreview($.Event());
- expect(this.view.modifyPostPreview).toHaveBeenCalled();
- });
});
describe('#setText', function() {
@@ -236,11 +220,9 @@ describe("app.views.Publisher", function() {
it("disables submitting", function() {
this.view.setText("TESTING");
expect(this.view.submitEl.prop("disabled")).toBeFalsy();
- expect(this.view.previewEl.prop("disabled")).toBeFalsy();
this.view.setEnabled(false);
expect(this.view.submitEl.prop("disabled")).toBeTruthy();
- expect(this.view.previewEl.prop("disabled")).toBeTruthy();
});
});
@@ -491,7 +473,6 @@ describe("app.views.Publisher", function() {
' '+
' '+
' '+
- ' '+
' '+
''
);
@@ -540,7 +521,6 @@ describe("app.views.Publisher", function() {
it('disables the publisher buttons', function() {
expect(this.view.submitEl.prop("disabled")).toBeTruthy();
- expect(this.view.previewEl.prop("disabled")).toBeTruthy();
});
});
@@ -577,7 +557,6 @@ describe("app.views.Publisher", function() {
it('re-enables the buttons', function() {
expect(this.view.submitEl.prop("disabled")).toBeFalsy();
- expect(this.view.previewEl.prop("disabled")).toBeFalsy();
});
});
diff --git a/spec/javascripts/helpers/markdown_editor_spec.js b/spec/javascripts/helpers/markdown_editor_spec.js
new file mode 100644
index 000000000..9c2ab4cff
--- /dev/null
+++ b/spec/javascripts/helpers/markdown_editor_spec.js
@@ -0,0 +1,237 @@
+describe("Diaspora.MarkdownEditor", function() {
+ beforeEach(function() {
+ spec.content().html("");
+ this.$el = $("#fake-textarea");
+ });
+
+ describe("constructor", function() {
+ it("calls initialize", function() {
+ spyOn(Diaspora.MarkdownEditor.prototype, "initialize");
+ new Diaspora.MarkdownEditor(this.$el, {});
+ expect(Diaspora.MarkdownEditor.prototype.initialize).toHaveBeenCalledWith(this.$el, {});
+ });
+ });
+
+ describe("initialize", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor($(""), {});
+ });
+
+ it("calls localize", function() {
+ spyOn(Diaspora.MarkdownEditor.prototype, "localize");
+ this.target.initialize(this.$el, {});
+ expect(Diaspora.MarkdownEditor.prototype.localize).toHaveBeenCalled();
+ });
+
+ it("calls onShow", function() {
+ spyOn(Diaspora.MarkdownEditor.prototype, "onShow");
+ this.target.initialize(this.$el, {});
+ expect(Diaspora.MarkdownEditor.prototype.onShow).toHaveBeenCalled();
+ });
+
+ it("call $.fn.markdown with correct default options", function() {
+ spyOn($.fn, "markdown");
+ this.target.initialize(this.$el, {});
+ expect($.fn.markdown).toHaveBeenCalled();
+ var args = $.fn.markdown.calls.mostRecent().args[0];
+ expect(args.resize).toBe("none");
+ expect(args.language).toBe("en");
+ expect(args.onHidePreview).toBe($.noop);
+ expect(args.onPostPreview).toBe($.noop);
+ expect(args.fullscreen).toEqual({enable: false, icons: {}});
+ expect(args.hiddenButtons).toEqual(["cmdPreview"]);
+ });
+
+ it("overrides fullscreen, hiddenButtons, language and onShow options", function() {
+ spyOn($.fn, "markdown").and.callThrough();
+ spyOn(Diaspora.MarkdownEditor.prototype, "onShow");
+ spyOn(Diaspora.MarkdownEditor.prototype, "localize").and.callThrough();
+ this.target.initialize(this.$el, {
+ fullscreen: {enabled: true, icons: {somekey: "somevalue"}},
+ hiddenButtons: [],
+ language: "fr",
+ onShow: $.noop
+ });
+ var args = $.fn.markdown.calls.mostRecent().args[0];
+ expect(args.fullscreen).toEqual({enable: false, icons: {}});
+ expect(args.hiddenButtons).toEqual(["cmdPreview"]);
+ expect(args.language).toBe("en");
+ expect(args.onShow).not.toBe($.noop);
+ expect(Diaspora.MarkdownEditor.prototype.onShow).toHaveBeenCalled();
+ expect(Diaspora.MarkdownEditor.prototype.localize).toHaveBeenCalled();
+ });
+ });
+
+ describe("onShow", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor(this.$el, {});
+ this.$el.find(".md-header").remove(".write-preview-tabs");
+ this.$el.find(".md-header").remove(".md-cancel");
+ });
+
+ it("retreives the $.fn.markdown instance back", function() {
+ var fakeInstance = {$editor: $("body")};
+ this.target.onShow(fakeInstance);
+ expect(this.target.instance).toBe(fakeInstance);
+ });
+
+ it("calls createTabsElement createCloseElement if preview and close functions are given", function() {
+ spyOn(Diaspora.MarkdownEditor.prototype, "createTabsElement");
+ spyOn(Diaspora.MarkdownEditor.prototype, "createCloseElement");
+ this.target.options.onPreview = $.noop;
+ this.target.options.onClose = $.noop;
+ this.target.onShow(this.target.instance);
+ expect(Diaspora.MarkdownEditor.prototype.createTabsElement).toHaveBeenCalled();
+ expect(Diaspora.MarkdownEditor.prototype.createCloseElement).toHaveBeenCalled();
+ });
+
+ it("does not call createTabsElement createCloseElement if no preview and close functions are given", function() {
+ spyOn(Diaspora.MarkdownEditor.prototype, "createTabsElement");
+ spyOn(Diaspora.MarkdownEditor.prototype, "createCloseElement");
+ delete this.target.options.onPreview;
+ delete this.target.options.onClose;
+ this.target.onShow(this.target.instance);
+ expect(Diaspora.MarkdownEditor.prototype.createCloseElement).not.toHaveBeenCalled();
+ expect(Diaspora.MarkdownEditor.prototype.createTabsElement).not.toHaveBeenCalled();
+ });
+
+ it("creates the preview and write tabs", function() {
+ this.target.options.onPreview = $.noop;
+ this.target.onShow(this.target.instance);
+ expect($(".md-header .write-preview-tabs").length).toBe(1);
+ });
+
+ it("removes preview tabs if already existing", function() {
+ this.target.options.onPreview = $.noop;
+ this.$el.find(".md-header").prepend("");
+ this.target.onShow(this.target.instance);
+ expect($(".md-header .write-preview-tabs").length).toBe(1);
+ expect($("#fake-write-preview-tabs").length).toBe(0);
+ });
+
+ it("creates the cancel button", function() {
+ this.target.options.onClose = $.noop;
+ this.target.onShow(this.target.instance);
+ expect($(".md-header .md-cancel").length).toBe(1);
+ });
+
+ it("removes cancel button if already existing", function() {
+ this.target.options.onClose = $.noop;
+ this.$el.find(".md-header").prepend("");
+ this.target.onShow(this.target.instance);
+ expect($(".md-header .md-cancel").length).toBe(1);
+ expect($("#fake-md-cancel").length).toBe(0);
+ });
+ });
+
+ describe("createTabsElement", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor(this.$el, {});
+ });
+
+ it("correctly creates the preview tabs", function() {
+ var tabsElement = this.target.createTabsElement();
+ expect(tabsElement).toHaveClass("write-preview-tabs");
+ expect(tabsElement.find("> li > a.md-write-tab").attr("title")).toBe("Edit message");
+ expect(tabsElement.find("> li > a.md-write-tab > i.diaspora-custom-compose").length).toBe(1);
+ expect(tabsElement.find("> li > a.md-write-tab > span.tab-help-text").length).toBe(1);
+ expect(tabsElement.find("> li > a.md-write-tab > span.tab-help-text").text()).toBe("Write");
+ expect(tabsElement.find("> li > a.md-preview-tab").attr("title")).toBe("Preview message");
+ expect(tabsElement.find("> li > a.md-preview-tab > i.entypo-search").length).toBe(1);
+ expect(tabsElement.find("> li > a.md-preview-tab > span.tab-help-text").length).toBe(1);
+ expect(tabsElement.find("> li > a.md-preview-tab > span.tab-help-text").text()).toBe("Preview");
+ });
+
+ it("correctly binds onclick events", function() {
+ var tabsElement = this.target.createTabsElement();
+ spyOn(Diaspora.MarkdownEditor.prototype, "hidePreview");
+ spyOn(Diaspora.MarkdownEditor.prototype, "showPreview");
+ tabsElement.find("> li > a.md-write-tab").click();
+ expect(Diaspora.MarkdownEditor.prototype.hidePreview).toHaveBeenCalled();
+ tabsElement.find("> li > a.md-preview-tab").click();
+ expect(Diaspora.MarkdownEditor.prototype.showPreview).toHaveBeenCalled();
+ });
+ });
+
+ describe("createCloseElement", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor(this.$el, {});
+ });
+
+ it("correctly creates the close button", function() {
+ var closeElement = this.target.createCloseElement();
+ expect(closeElement).toHaveClass("md-cancel");
+ expect(closeElement.get(0).tagName).toBe("A");
+ expect(closeElement.attr("title")).toBe("Cancel message");
+ expect(closeElement.find("> i.entypo-cross").length).toBe(1);
+ });
+
+ it("correctly binds onclick events", function() {
+ this.target.options.onClose = jasmine.createSpy();
+ var closeElement = this.target.createCloseElement();
+ closeElement.click();
+ expect(this.target.options.onClose).toHaveBeenCalled();
+ });
+ });
+
+ describe("hidePreview", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor(this.$el, {onPreview: $.noop, onHidePreview: jasmine.createSpy()});
+ spyOn(this.target.instance, "hidePreview");
+ spyOn(this.target.writeLink, "tab");
+ });
+
+ it("calls writeLink.tab", function() {
+ this.target.hidePreview();
+ expect(this.target.writeLink.tab).toHaveBeenCalledWith("show");
+ });
+
+ it("calls instance.hidePreview", function() {
+ this.target.hidePreview();
+ expect(this.target.instance.hidePreview).toHaveBeenCalled();
+ });
+
+ it("calls instance.onHidePreview", function() {
+ this.target.hidePreview();
+ expect(this.target.options.onHidePreview).toHaveBeenCalled();
+ });
+ });
+
+ describe("showPreview", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor(this.$el, {onPreview: $.noop, onPostPreview: jasmine.createSpy()});
+ spyOn(this.target.instance, "showPreview");
+ spyOn(this.target.previewLink, "tab");
+ });
+
+ it("calls previewLink.tab", function() {
+ this.target.showPreview();
+ expect(this.target.previewLink.tab).toHaveBeenCalledWith("show");
+ });
+
+ it("calls instance.showPreview", function() {
+ this.target.showPreview();
+ expect(this.target.instance.showPreview).toHaveBeenCalled();
+ });
+
+ it("calls instance.onPostPreview", function() {
+ this.target.showPreview();
+ expect(this.target.options.onPostPreview).toHaveBeenCalled();
+ });
+ });
+
+ describe("localize", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor(this.$el, {});
+ });
+
+ it("returns the correct locale", function() {
+ expect(this.target.localize()).toBe(Diaspora.I18n.language);
+ });
+
+ it("creates translation messages for the current locale", function() {
+ this.target.localize();
+ expect($.fn.markdown.messages[Diaspora.I18n.language]).toBeDefined();
+ });
+ });
+});
diff --git a/spec/javascripts/jasmine_helpers/factory.js b/spec/javascripts/jasmine_helpers/factory.js
index 1659574ff..d21435651 100644
--- a/spec/javascripts/jasmine_helpers/factory.js
+++ b/spec/javascripts/jasmine_helpers/factory.js
@@ -76,6 +76,7 @@ var factory = {
postAttrs : function(){
return {
+ "author": {},
"provider_display_name" : null,
"created_at" : "2012-01-03T19:53:13Z",
"interacted_at" : '2012-01-03T19:53:13Z',