diff --git a/Gemfile b/Gemfile
index 0dd8f16ab..1017a84ac 100644
--- a/Gemfile
+++ b/Gemfile
@@ -128,6 +128,9 @@ gem "rails-i18n", "4.0.4"
gem "markerb", "1.0.2"
gem "messagebus_ruby_api", "1.0.3"
+# Map
+gem "leaflet-rails", "0.7.4"
+
# Parsing
gem "nokogiri", "1.6.6.2"
diff --git a/Gemfile.lock b/Gemfile.lock
index 250f3e955..a73133859 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -409,6 +409,7 @@ GEM
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.9.3)
+ leaflet-rails (0.7.4)
listen (3.0.3)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
@@ -833,6 +834,7 @@ DEPENDENCIES
jshintrb (= 0.3.0)
json (= 1.8.3)
json-schema (= 2.5.1)
+ leaflet-rails (= 0.7.4)
logging-rails (= 0.5.0)
markerb (= 1.0.2)
messagebus_ruby_api (= 1.0.3)
diff --git a/app/assets/javascripts/app/views/content_view.js b/app/assets/javascripts/app/views/content_view.js
index bd00d36a4..20ddadb0d 100644
--- a/app/assets/javascripts/app/views/content_view.js
+++ b/app/assets/javascripts/app/views/content_view.js
@@ -29,7 +29,6 @@ app.views.Content = app.views.Base.extend({
return photos;
},
-
expandPost: function(evt) {
var el = $(this.el).find('.collapsible');
el.removeClass('collapsed').addClass('opened');
@@ -155,4 +154,5 @@ app.views.SPVOpenGraph = app.views.OpenGraph.extend({
// override with nothing
}
});
+
// @license-end
diff --git a/app/assets/javascripts/app/views/location_map.js b/app/assets/javascripts/app/views/location_map.js
new file mode 100644
index 000000000..e499e2371
--- /dev/null
+++ b/app/assets/javascripts/app/views/location_map.js
@@ -0,0 +1,34 @@
+// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
+
+app.views.LocationMap = app.views.Content.extend({
+ templateName: "status-message-map",
+
+ map: function() {
+ var coordinates = this.model.get("coordinates");
+
+ // if (coordinates != "" && tileserver.enable) { // for when the tileserver is set via the diaspora.yml
+ if (coordinates.lat) {
+ var tileLayerSource = "https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}";
+ var map = L.map("map").setView([coordinates.lat, coordinates.lng], 16);
+ var attribution = "Map data © OpenStreetMap contributors, " +
+ "CC-BY-SA, " +
+ "Imagery © Mapbox";
+
+ L.tileLayer(tileLayerSource, {
+ attribution: attribution,
+ maxZoom: 18,
+ id: "zaziemo.mpn66kn8",
+ accessToken: "pk.eyJ1IjoiemF6aWVtbyIsImEiOiI3ODVjMzVjNmM2ZTU3YWM3YTE5YWYwMTRhODljM2M1MSJ9.-nVgyS4PLnV4m9YkvMB5wA"
+ }).addTo(map);
+
+ var markerOnMap = L.marker(coordinates).addTo(map);
+
+ return map;
+ }
+ },
+
+ postRenderTemplate : function(){
+ _.defer(_.bind(this.map, this));
+ }
+});
+// @license-end
diff --git a/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js b/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js
index 57bbbb791..92e5cb29e 100644
--- a/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js
+++ b/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js
@@ -11,7 +11,8 @@ app.views.SinglePostContent = app.views.Base.extend({
".oembed" : "oEmbedView",
".opengraph" : "openGraphView",
".status-message-location" : "postLocationStreamView",
- ".poll": "pollView"
+ ".map" : "postMapView",
+ '.poll': 'pollView',
},
initialize : function() {
@@ -20,6 +21,7 @@ app.views.SinglePostContent = app.views.Base.extend({
this.oEmbedView = new app.views.OEmbed({model : this.model});
this.openGraphView = new app.views.SPVOpenGraph({model : this.model});
this.postContentView = new app.views.ExpandedStatusMessage({model: this.model});
+ this.postMapView = new app.views.LocationMap({model: this.model});
this.pollView = new app.views.Poll({ model: this.model });
},
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 93891fb97..adc3bcc7a 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -45,3 +45,4 @@
//= require osmlocator
//= require bootstrap-switch
//= require blueimp-gallery
+//= require leaflet
diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss
index b47584a22..edabd4527 100644
--- a/app/assets/stylesheets/_application.scss
+++ b/app/assets/stylesheets/_application.scss
@@ -42,6 +42,10 @@
@import 'single-post-view';
@import 'new_styles/poll';
+/* map*/
+@import 'leaflet';
+@import 'map';
+
/* conversations */
@import 'conversations';
diff --git a/app/assets/stylesheets/map.scss b/app/assets/stylesheets/map.scss
new file mode 100644
index 000000000..f210f8dbb
--- /dev/null
+++ b/app/assets/stylesheets/map.scss
@@ -0,0 +1,13 @@
+#map {
+ height: 180px;
+ position: relative;
+ overflow: hidden;
+}
+
+.leaflet-bottom .leaflet-control {
+ margin-bottom: 0;
+}
+
+.leaflet-right .leaflet-control {
+ margin-right: 0;
+}
diff --git a/app/assets/stylesheets/single-post-view.scss b/app/assets/stylesheets/single-post-view.scss
index 82bf4d5bc..71ca37235 100644
--- a/app/assets/stylesheets/single-post-view.scss
+++ b/app/assets/stylesheets/single-post-view.scss
@@ -13,6 +13,7 @@
color: lighten($text-grey,10%);
font-size: 12px;
.post-time a { color: $text-grey; }
+ .near-from a { color: $text-grey; }
.post_scope { margin-right: 5px; }
.status-message-location {
padding-top: 2px;
diff --git a/app/assets/stylesheets/stream_element.scss b/app/assets/stylesheets/stream_element.scss
index 9b2861c5a..1cf764c64 100644
--- a/app/assets/stylesheets/stream_element.scss
+++ b/app/assets/stylesheets/stream_element.scss
@@ -83,7 +83,7 @@
float: left;
margin-top: 6px;
}
- .status-message-location .near-from {
+ .status-message-location .near-from a {
font-size: $font-size-small;
color: $text-grey;
}
diff --git a/app/assets/templates/single-post-viewer/single-post-content_tpl.jst.hbs b/app/assets/templates/single-post-viewer/single-post-content_tpl.jst.hbs
index 7c61fe741..4da6a3ead 100644
--- a/app/assets/templates/single-post-viewer/single-post-content_tpl.jst.hbs
+++ b/app/assets/templates/single-post-viewer/single-post-content_tpl.jst.hbs
@@ -99,4 +99,5 @@
diff --git a/app/assets/templates/status-message-location_tpl.jst.hbs b/app/assets/templates/status-message-location_tpl.jst.hbs
index c6c7ea7ec..0d648125c 100644
--- a/app/assets/templates/status-message-location_tpl.jst.hbs
+++ b/app/assets/templates/status-message-location_tpl.jst.hbs
@@ -1,5 +1,5 @@
{{#if location}}
{{/if}}
diff --git a/app/assets/templates/status-message-map_tpl.jst.hbs b/app/assets/templates/status-message-map_tpl.jst.hbs
new file mode 100644
index 000000000..87207d39c
--- /dev/null
+++ b/app/assets/templates/status-message-map_tpl.jst.hbs
@@ -0,0 +1,4 @@
+{{#if location}}
+
+
+{{/if}}
diff --git a/app/models/reshare.rb b/app/models/reshare.rb
index 93803af1d..f3cbdb2ed 100644
--- a/app/models/reshare.rb
+++ b/app/models/reshare.rb
@@ -3,7 +3,6 @@
# the COPYRIGHT file.
class Reshare < Post
-
belongs_to :root, :class_name => 'Post', :foreign_key => :root_guid, :primary_key => :guid
validate :root_must_be_public
validates_presence_of :root, :on => :create
@@ -49,6 +48,10 @@ class Reshare < Post
absolute_root.try(:location).try(:address)
end
+ def coordinates
+ {lat: absolute_root.try(:location).try(:lat), lng: absolute_root.try(:location).try(:lng)}
+ end
+
def poll
absolute_root.try(:poll) || super
end
diff --git a/app/models/status_message.rb b/app/models/status_message.rb
index 4dacee42c..b69a682d6 100644
--- a/app/models/status_message.rb
+++ b/app/models/status_message.rb
@@ -162,6 +162,10 @@ class StatusMessage < Post
location.try(:address)
end
+ def coordinates
+ {lat: location.try(:lat), lng: location.try(:lng)}
+ end
+
protected
def presence_of_content
if text_and_photos_blank?
diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb
index b1df1a917..ea77b1530 100644
--- a/app/presenters/post_presenter.rb
+++ b/app/presenters/post_presenter.rb
@@ -32,6 +32,7 @@ class PostPresenter < BasePresenter
root: root,
title: title,
address: @post.address,
+ coordinates: @post.coordinates,
poll: @post.poll,
already_participated_in_poll: already_participated_in_poll,
participation: participate?,
diff --git a/spec/factories.rb b/spec/factories.rb
index 1f99c0f0b..a7cddc2b7 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -140,9 +140,10 @@ FactoryGirl.define do
end
factory(:location) do
- address "unicorn city"
- lat 1
- lng 2
+ address "Starco Mart, Mission Street, West SoMa, San Francisco, San Francisco "\
+ "City and County, Kalifornien, 94103, Vereinigte Staaten von Amerika"
+ lat 37.78
+ lng -122.41
end
factory(:poll) do
diff --git a/spec/javascripts/app/views/content_view_spec.js b/spec/javascripts/app/views/content_view_spec.js
index 6a701aaa3..218bc4e0f 100644
--- a/spec/javascripts/app/views/content_view_spec.js
+++ b/spec/javascripts/app/views/content_view_spec.js
@@ -24,5 +24,11 @@ describe("app.views.Content", function(){
this.post.set({post_type : "Reshare"});
expect(this.view.presenter().isReshare).toBeTruthy();
});
+
+ // it("provides coordinates", function(){
+ // this.post.location;
+ // console.log(this.view.presenter());
+ // console.log(this.post.location);
+ // });
});
});
diff --git a/spec/models/reshare_spec.rb b/spec/models/reshare_spec.rb
index e235c4066..3661bae94 100644
--- a/spec/models/reshare_spec.rb
+++ b/spec/models/reshare_spec.rb
@@ -1,33 +1,33 @@
-require 'spec_helper'
+require "spec_helper"
-describe Reshare, :type => :model do
- it 'has a valid Factory' do
+describe Reshare, type: :model do
+ it "has a valid Factory" do
expect(FactoryGirl.build(:reshare)).to be_valid
end
- it 'requires root' do
- reshare = FactoryGirl.build(:reshare, :root => nil)
+ it "requires root" do
+ reshare = FactoryGirl.build(:reshare, root: nil)
expect(reshare).not_to be_valid
end
- it 'require public root' do
- reshare = FactoryGirl.build(:reshare, :root => FactoryGirl.create(:status_message, :public => false))
+ it "require public root" do
+ reshare = FactoryGirl.build(:reshare, root: FactoryGirl.create(:status_message, public: false))
expect(reshare).not_to be_valid
- expect(reshare.errors[:base]).to include('Only posts which are public may be reshared.')
+ expect(reshare.errors[:base]).to include("Only posts which are public may be reshared.")
end
- it 'forces public' do
- expect(FactoryGirl.create(:reshare, :public => false).public).to be true
+ it "forces public" do
+ expect(FactoryGirl.create(:reshare, public: false).public).to be true
end
describe "#root_diaspora_id" do
+ let(:reshare) { create(:reshare, root: FactoryGirl.build(:status_message, author: bob.person, public: true)) }
+
it "should return the root diaspora id" do
- reshare = FactoryGirl.create(:reshare, root: FactoryGirl.build(:status_message, author: bob.person, public: true))
expect(reshare.root_diaspora_id).to eq(bob.person.diaspora_handle)
end
it "should be nil if no root found" do
- reshare = FactoryGirl.create(:reshare, root: FactoryGirl.build(:status_message, author: bob.person, public: true))
reshare.root = nil
expect(reshare.root_diaspora_id).to be_nil
end
@@ -37,195 +37,188 @@ describe Reshare, :type => :model do
let(:receive_reshare) { @reshare.receive(@root.author.owner, @reshare.author) }
before do
- @reshare = FactoryGirl.create(:reshare, :root => FactoryGirl.build(:status_message, :author => bob.person, :public => true))
+ @reshare = FactoryGirl.create(:reshare, root:
+ FactoryGirl.build(:status_message, author: bob.person, public: true))
@root = @reshare.root
end
- it 'increments the reshare count' do
+ it "increments the reshare count" do
receive_reshare
expect(@root.resharers.count).to eq(1)
end
- it 'adds the resharer to the re-sharers of the post' do
+ it "adds the resharer to the re-sharers of the post" do
receive_reshare
expect(@root.resharers).to include(@reshare.author)
end
- it 'does not error if the root author has a contact for the resharer' do
+ it "does not error if the root author has a contact for the resharer" do
bob.share_with @reshare.author, bob.aspects.first
expect {
Timeout.timeout(5) do
- receive_reshare #This doesn't ever terminate on my machine before it was fixed.
+ receive_reshare # This doesn't ever terminate on my machine before it was fixed.
end
}.not_to raise_error
end
end
- describe '#nsfw' do
- before do
- sfw = FactoryGirl.build(:status_message, :author => alice.person, :public => true)
- nsfw = FactoryGirl.build(:status_message, :author => alice.person, :public => true, :text => "This is #nsfw")
- @sfw_reshare = FactoryGirl.build(:reshare, :root => sfw)
- @nsfw_reshare = FactoryGirl.build(:reshare, :root => nsfw)
- end
+ describe "#nsfw" do
+ let(:sfw) { build(:status_message, author: alice.person, public: true) }
+ let(:nsfw) { build(:status_message, author: alice.person, public: true, text: "This is #nsfw") }
+ let(:sfw_reshare) { build(:reshare, root: sfw) }
+ let(:nsfw_reshare) { build(:reshare, root: nsfw) }
- it 'deletates #nsfw to the root post' do
- expect(@sfw_reshare.nsfw).not_to be true
- expect(@nsfw_reshare.nsfw).to be_truthy
+ it "deletates #nsfw to the root post" do
+ expect(sfw_reshare.nsfw).not_to be true
+ expect(nsfw_reshare.nsfw).to be_truthy
end
end
- describe '#poll' do
- before do
- @root_post = FactoryGirl.create(:status_message_with_poll, public: true)
- @reshare = FactoryGirl.create(:reshare, root: @root_post)
- end
+ describe "#poll" do
+ let(:root_post) { create(:status_message_with_poll, public: true) }
+ let(:reshare) { create(:reshare, root: root_post) }
- it 'contains root poll' do
- expect(@reshare.poll).to eq @root_post.poll
+ it "contains root poll" do
+ expect(reshare.poll).to eq root_post.poll
end
end
- describe '#notification_type' do
- before do
- sm = FactoryGirl.build(:status_message, :author => alice.person, :public => true)
- @reshare = FactoryGirl.build(:reshare, :root => sm)
- end
- it 'does not return anything for non-author of the original post' do
- expect(@reshare.notification_type(bob, @reshare.author)).to be_nil
+ describe "#notification_type" do
+ let(:status_message) { build(:status_message, author: alice.person, public: true) }
+ let(:reshare) { build(:reshare, root: status_message) }
+
+ it "does not return anything for non-author of the original post" do
+ expect(reshare.notification_type(bob, reshare.author)).to be_nil
end
- it 'returns "Reshared" for the original post author' do
- expect(@reshare.notification_type(alice, @reshare.author)).to eq(Notifications::Reshared)
+ it "returns 'Reshared' for the original post author" do
+ expect(reshare.notification_type(alice, reshare.author)).to eq(Notifications::Reshared)
end
- it 'does not error out if the root was deleted' do
- @reshare.root = nil
+ it "does not error out if the root was deleted" do
+ reshare.root = nil
expect {
- @reshare.notification_type(alice, @reshare.author)
+ reshare.notification_type(alice, reshare.author)
}.to_not raise_error
end
end
- describe '#absolute_root' do
+ describe "#absolute_root" do
before do
- @sm = FactoryGirl.build(:status_message, :author => alice.person, :public => true)
- rs1 = FactoryGirl.build(:reshare, :root=>@sm)
- rs2 = FactoryGirl.build(:reshare, :root=>rs1)
- @rs3 = FactoryGirl.build(:reshare, :root=>rs2)
+ @status_message = FactoryGirl.build(:status_message, author: alice.person, public: true)
+ reshare_1 = FactoryGirl.build(:reshare, root: @status_message)
+ reshare_2 = FactoryGirl.build(:reshare, root: reshare_1)
+ @reshare_3 = FactoryGirl.build(:reshare, root: reshare_2)
- sm = FactoryGirl.create(:status_message, :author => alice.person, :public => true)
- rs1 = FactoryGirl.create(:reshare, :root => sm)
- @of_deleted = FactoryGirl.build(:reshare, :root => rs1)
- sm.destroy
- rs1.reload
+ status_message = FactoryGirl.create(:status_message, author: alice.person, public: true)
+ reshare_1 = FactoryGirl.create(:reshare, root: status_message)
+ @of_deleted = FactoryGirl.build(:reshare, root: reshare_1)
+ status_message.destroy
+ reshare_1.reload
end
- it 'resolves root posts to the top level' do
- expect(@rs3.absolute_root).to eq(@sm)
+ it "resolves root posts to the top level" do
+ expect(@reshare_3.absolute_root).to eq(@status_message)
end
- it 'can handle deleted reshares' do
+ it "can handle deleted reshares" do
expect(@of_deleted.absolute_root).to be_nil
end
- it 'is used everywhere' do
- expect(@rs3.message).to eq @sm.message
+ it "is used everywhere" do
+ expect(@reshare_3.message).to eq @status_message.message
expect(@of_deleted.message).to be_nil
- expect(@rs3.photos).to eq @sm.photos
+ expect(@reshare_3.photos).to eq @status_message.photos
expect(@of_deleted.photos).to be_empty
- expect(@rs3.o_embed_cache).to eq @sm.o_embed_cache
+ expect(@reshare_3.o_embed_cache).to eq @status_message.o_embed_cache
expect(@of_deleted.o_embed_cache).to be_nil
- expect(@rs3.open_graph_cache).to eq @sm.open_graph_cache
+ expect(@reshare_3.open_graph_cache).to eq @status_message.open_graph_cache
expect(@of_deleted.open_graph_cache).to be_nil
- expect(@rs3.mentioned_people).to eq @sm.mentioned_people
+ expect(@reshare_3.mentioned_people).to eq @status_message.mentioned_people
expect(@of_deleted.mentioned_people).to be_empty
- expect(@rs3.nsfw).to eq @sm.nsfw
+ expect(@reshare_3.nsfw).to eq @status_message.nsfw
expect(@of_deleted.nsfw).to be_nil
- expect(@rs3.address).to eq @sm.location.try(:address)
+ expect(@reshare_3.address).to eq @status_message.location.try(:address)
expect(@of_deleted.address).to be_nil
end
end
describe "XML" do
- before do
- @reshare = FactoryGirl.build(:reshare)
- @xml = @reshare.to_xml.to_s
- end
+ let(:reshare) { build(:reshare) }
+ let(:xml) { reshare.to_xml.to_s }
- context 'serialization' do
- it 'serializes root_diaspora_id' do
- expect(@xml).to include("root_diaspora_id")
- expect(@xml).to include(@reshare.author.diaspora_handle)
+ context "serialization" do
+ it "serializes root_diaspora_id" do
+ expect(xml).to include("root_diaspora_id")
+ expect(xml).to include(reshare.author.diaspora_handle)
end
- it 'serializes root_guid' do
- expect(@xml).to include("root_guid")
- expect(@xml).to include(@reshare.root.guid)
+ it "serializes root_guid" do
+ expect(xml).to include("root_guid")
+ expect(xml).to include(reshare.root.guid)
end
end
- context 'marshalling' do
- context 'local' do
- before do
- @original_author = @reshare.root.author
- @root_object = @reshare.root
+ context "marshalling" do
+ let(:root_object) { reshare.root }
+
+ context "local" do
+ let(:original_author) { reshare.root.author }
+
+ it "marshals the guid" do
+ expect(Reshare.from_xml(xml).root_guid).to eq(root_object.guid)
end
- it 'marshals the guid' do
- expect(Reshare.from_xml(@xml).root_guid).to eq(@root_object.guid)
+ it "fetches the root post from root_guid" do
+ expect(Reshare.from_xml(xml).root).to eq(root_object)
end
- it 'fetches the root post from root_guid' do
- expect(Reshare.from_xml(@xml).root).to eq(@root_object)
- end
-
- it 'fetches the root author from root_diaspora_id' do
- expect(Reshare.from_xml(@xml).root.author).to eq(@original_author)
+ it "fetches the root author from root_diaspora_id" do
+ expect(Reshare.from_xml(xml).root.author).to eq(original_author)
end
end
- describe 'destroy' do
- it 'allows you to destroy the reshare if the root post is missing' do
- reshare = FactoryGirl.build(:reshare)
+ describe "destroy" do
+ it "allows you to destroy the reshare if the root post is missing" do
+ reshare
reshare.root = nil
- expect{
+ expect {
reshare.destroy
}.to_not raise_error
end
end
- context 'remote' do
+ context "remote" do
before do
- @root_object = @reshare.root
- @root_object.delete
+ # root_object = reshare.root
+ root_object.delete
@response = double
allow(@response).to receive(:status).and_return(200)
allow(@response).to receive(:success?).and_return(true)
end
- it 'fetches the root author from root_diaspora_id' do
- @original_profile = @reshare.root.author.profile.dup
- @reshare.root.author.profile.delete
- @original_author = @reshare.root.author.dup
- @reshare.root.author.delete
+ it "fetches the root author from root_diaspora_id" do
+ @original_profile = reshare.root.author.profile.dup
+ reshare.root.author.profile.delete
+ @original_author = reshare.root.author.dup
+ reshare.root.author.delete
@original_author.profile = @original_profile
expect(Person).to receive(:find_or_fetch_by_identifier).and_return(@original_author)
- allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml)
+ allow(@response).to receive(:body).and_return(root_object.to_diaspora_xml)
expect(Faraday.default_connection).to receive(:get).with(
URI.join(
@original_author.url,
Rails.application.routes.url_helpers.short_post_path(
- @root_object.guid,
+ root_object.guid,
format: "xml"
)
)
).and_return(@response)
- Reshare.from_xml(@xml)
+ Reshare.from_xml(xml)
end
context "fetching post" do
@@ -234,7 +227,7 @@ describe Reshare, :type => :model do
expect(Faraday.default_connection).to receive(:get).and_return(@response)
expect {
- Reshare.from_xml(@xml)
+ Reshare.from_xml(xml)
}.to raise_error(Diaspora::PostNotFetchable)
end
@@ -244,57 +237,78 @@ describe Reshare, :type => :model do
expect(Faraday.default_connection).to receive(:get).and_return(@response)
expect {
- Reshare.from_xml(@xml)
+ Reshare.from_xml(xml)
}.to raise_error RuntimeError
end
end
- context 'saving the post' do
+ context "saving the post" do
before do
- allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml)
+ allow(@response).to receive(:body).and_return(root_object.to_diaspora_xml)
allow(Faraday.default_connection).to receive(:get).with(
URI.join(
- @reshare.root.author.url,
+ reshare.root.author.url,
Rails.application.routes.url_helpers.short_post_path(
- @root_object.guid,
+ root_object.guid,
format: "xml"
)
)
).and_return(@response)
end
- it 'fetches the root post from root_guid' do
- root = Reshare.from_xml(@xml).root
+ it "fetches the root post from root_guid" do
+ root = Reshare.from_xml(xml).root
- [:text, :guid, :diaspora_handle, :type, :public].each do |attr|
- expect(root.send(attr)).to eq(@reshare.root.send(attr))
+ %i(text guid diaspora_handle type public).each do |attr|
+ expect(root.send(attr)).to eq(reshare.root.send(attr))
end
end
- it 'correctly saves the type' do
- expect(Reshare.from_xml(@xml).root.reload.type).to eq("StatusMessage")
+ it "correctly saves the type" do
+ expect(Reshare.from_xml(xml).root.reload.type).to eq("StatusMessage")
end
- it 'correctly sets the author' do
- @original_author = @reshare.root.author
- expect(Reshare.from_xml(@xml).root.reload.author.reload).to eq(@original_author)
+ it "correctly sets the author" do
+ @original_author = reshare.root.author
+ expect(Reshare.from_xml(xml).root.reload.author.reload).to eq(@original_author)
end
- it 'verifies that the author of the post received is the same as the author in the reshare xml' do
- @original_author = @reshare.root.author.dup
- @xml = @reshare.to_xml.to_s
+ it "verifies that the author of the post received is the same as the author in the reshare xml" do
+ @original_author = reshare.root.author.dup
+ xml = reshare.to_xml.to_s
different_person = FactoryGirl.build(:person)
expect(Person).to receive(:find_or_fetch_by_identifier).and_return(different_person)
allow(different_person).to receive(:url).and_return(@original_author.url)
- expect{
- Reshare.from_xml(@xml)
+ expect {
+ Reshare.from_xml(xml)
}.to raise_error /^Diaspora ID \(.+\) in the root does not match the Diaspora ID \(.+\) specified in the reshare!$/
end
end
end
end
end
+
+ describe ".coordinates" do
+ let(:status_message) { build(:status_message, text: "This is a status_message", author: bob.person, public: true) }
+ let(:reshare) { create(:reshare, root: status_message) }
+
+ context "with location" do
+ let(:location) { build(:location) }
+
+ it "should deliver coordinates" do
+ status_message.location = location
+ expect(reshare.coordinates).to include(lat: location.lat, lng: location.lng)
+ end
+ end
+
+ context "without location" do
+ it "should deliver empty coordinates" do
+ expect(reshare.coordinates[:lat]).to be_nil
+ expect(reshare.coordinates[:lng]).to be_nil
+ end
+ end
+ end
end
diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb
index 0f37390a4..6b1523bce 100644
--- a/spec/models/status_message_spec.rb
+++ b/spec/models/status_message_spec.rb
@@ -2,56 +2,54 @@
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
-require 'spec_helper'
+require "spec_helper"
-describe StatusMessage, :type => :model do
+describe StatusMessage, type: :model do
include PeopleHelper
- before do
- @user = alice
- @aspect = @user.aspects.first
- end
+ let!(:user) { alice }
+ let!(:aspect) { user.aspects.first }
+ let(:status) { build(:status_message) }
- describe 'scopes' do
- describe '.where_person_is_mentioned' do
- it 'returns status messages where the given person is mentioned' do
- @bo = bob.person
- @test_string = "@{Daniel; #{@bo.diaspora_handle}} can mention people like Raph"
+ describe "scopes" do
+ describe ".where_person_is_mentioned" do
+ it "returns status messages where the given person is mentioned" do
+ @bob = bob.person
+ @test_string = "@{Daniel; #{@bob.diaspora_handle}} can mention people like Raph"
+ FactoryGirl.create(:status_message, text: @test_string)
+ FactoryGirl.create(:status_message, text: @test_string)
+ FactoryGirl.create(:status_message)
- FactoryGirl.create(:status_message, :text => @test_string )
- FactoryGirl.create(:status_message, :text => @test_string )
- FactoryGirl.create(:status_message)
-
- expect(StatusMessage.where_person_is_mentioned(@bo).count).to eq(2)
+ expect(StatusMessage.where_person_is_mentioned(bob).count).to eq(2)
end
end
context "tag_streams" do
before do
- @sm1 = FactoryGirl.create(:status_message, :text => "#hashtag" , :public => true)
- @sm2 = FactoryGirl.create(:status_message, :text => "#hashtag" )
- @sm3 = FactoryGirl.create(:status_message, :text => "hashtags are #awesome", :public => true )
- @sm4 = FactoryGirl.create(:status_message, :text => "hashtags are #awesome" )
+ @status_message_1 = FactoryGirl.create(:status_message, text: "#hashtag", public: true)
+ @status_message_2 = FactoryGirl.create(:status_message, text: "#hashtag")
+ @status_message_3 = FactoryGirl.create(:status_message, text: "hashtags are #awesome", public: true)
+ @status_message_4 = FactoryGirl.create(:status_message, text: "hashtags are #awesome")
- @tag_id = ActsAsTaggableOn::Tag.where(:name => "hashtag").first.id
+ @tag_id = ActsAsTaggableOn::Tag.where(name: "hashtag").first.id
end
- describe '.tag_steam' do
- it 'returns status messages tagged with the tag' do
+ describe ".tag_steam" do
+ it "returns status messages tagged with the tag" do
tag_stream = StatusMessage.send(:tag_stream, [@tag_id])
- expect(tag_stream).to include @sm1
- expect(tag_stream).to include @sm2
+ expect(tag_stream).to include @status_message_1
+ expect(tag_stream).to include @status_message_2
end
end
- describe '.public_tag_stream' do
- it 'returns public status messages tagged with the tag' do
- expect(StatusMessage.public_tag_stream([@tag_id])).to eq([@sm1])
+ describe ".public_tag_stream" do
+ it "returns public status messages tagged with the tag" do
+ expect(StatusMessage.public_tag_stream([@tag_id])).to eq([@status_message_1])
end
end
- describe '.user_tag_stream' do
- it 'returns tag stream thats owned or visible by' do
+ describe ".user_tag_stream" do
+ it "returns tag stream thats owned or visible by" do
relation = double
expect(StatusMessage).to receive(:owned_or_visible_by_user).with(bob).and_return(relation)
expect(relation).to receive(:tag_stream).with([@tag_id])
@@ -63,48 +61,45 @@ describe StatusMessage, :type => :model do
end
describe ".guids_for_author" do
- it 'returns an array of the status_message guids' do
- sm1 = FactoryGirl.create(:status_message, :author => alice.person)
- sm2 = FactoryGirl.create(:status_message, :author => bob.person)
+ it "returns an array of the status_message guids" do
+ status_message_1 = FactoryGirl.create(:status_message, author: alice.person)
+ status_message_2 = FactoryGirl.create(:status_message, author: bob.person)
guids = StatusMessage.guids_for_author(alice.person)
- expect(guids).to eq([sm1.guid])
+ expect(guids).to eq([status_message_1.guid])
end
end
- describe '.before_validation' do
- it 'calls build_tags' do
- status = FactoryGirl.build(:status_message)
+ describe ".before_validation" do
+ it "calls build_tags" do
expect(status).to receive(:build_tags)
status.save
end
end
- describe '.before_create' do
- it 'calls build_tags' do
- status = FactoryGirl.build(:status_message)
+ describe ".before_create" do
+ it "calls build_tags" do
expect(status).to receive(:build_tags)
status.save
end
- it 'calls filter_mentions' do
- status = FactoryGirl.build(:status_message)
+ it "calls filter_mentions" do
expect(status).to receive(:filter_mentions)
status.save
end
end
- describe '.after_create' do
- it 'calls create_mentions' do
+ describe ".after_create" do
+ it "calls create_mentions" do
status = FactoryGirl.build(:status_message, text: "text @{Test; #{alice.diaspora_handle}}")
expect(status).to receive(:create_mentions).and_call_original
status.save
end
end
- describe '#diaspora_handle=' do
- it 'sets #author' do
+ describe "#diaspora_handle=" do
+ it "sets #author" do
person = FactoryGirl.create(:person)
- post = FactoryGirl.build(:status_message, :author => @user.person)
+ post = FactoryGirl.build(:status_message, author: user.person)
post.diaspora_handle = person.diaspora_handle
expect(post.author).to eq(person)
end
@@ -112,105 +107,104 @@ describe StatusMessage, :type => :model do
context "emptyness" do
it "needs either a message or at least one photo" do
- n = @user.build_post(:status_message, :text => nil)
- expect(n).not_to be_valid
+ post = user.build_post(:status_message, text: nil)
+ expect(post).not_to be_valid
- n.text = ""
- expect(n).not_to be_valid
+ post.text = ""
+ expect(post).not_to be_valid
- n.text = "wales"
- expect(n).to be_valid
- n.text = nil
+ post.text = "wales"
+ expect(post).to be_valid
+ post.text = nil
- photo = @user.build_post(:photo, :user_file => uploaded_photo, :to => @aspect.id)
+ photo = user.build_post(:photo, user_file: uploaded_photo, to: aspect.id)
photo.save!
- n.photos << photo
- expect(n).to be_valid
- expect(n.errors.full_messages).to eq([])
+ post.photos << photo
+ expect(post).to be_valid
+ expect(post.errors.full_messages).to eq([])
end
it "doesn't check for content when author is remote (federation...)" do
- p = FactoryGirl.build(:status_message, text: nil)
- expect(p).to be_valid
+ post = FactoryGirl.build(:status_message, text: nil)
+ expect(post).to be_valid
end
end
- it 'should be postable through the user' do
+ it "should be postable through the user" do
message = "Users do things"
- status = @user.post(:status_message, :text => message, :to => @aspect.id)
+ status = user.post(:status_message, text: message, to: aspect.id)
db_status = StatusMessage.find(status.id)
expect(db_status.text).to eq(message)
end
- it 'should require status messages not be more than 65535 characters long' do
- message = 'a' * (65535+1)
- status_message = FactoryGirl.build(:status_message, :text => message)
+ it "should require status messages not be more than 65535 characters long" do
+ message = "a" * (65_535 + 1)
+ status_message = FactoryGirl.build(:status_message, text: message)
expect(status_message).not_to be_valid
end
- describe 'mentions' do
- before do
- @people = [alice, bob, eve].map{|u| u.person}
- @test_string = <<-STR
-@{Raphael; #{@people[0].diaspora_handle}} can mention people like Raphael @{Ilya; #{@people[1].diaspora_handle}}
-can mention people like Raphaellike Raphael @{Daniel; #{@people[2].diaspora_handle}} can mention people like Raph
-STR
- @sm = FactoryGirl.create(:status_message, :text => @test_string )
- end
+ describe "mentions" do
+ let(:people) { [alice, bob, eve].map(&:person) }
+ let(:test_string) {
+ "@{Raphael; #{people[0].diaspora_handle}} can mention people like Raphael @{Ilya; #{people[1].diaspora_handle}}
+ can mention people like Raphaellike Raphael @{Daniel; #{people[2].diaspora_handle}} can mention people like Raph"
+ }
+ let(:status_message) { create(:status_message, text: test_string) }
- describe '#create_mentions' do
- it 'creates a mention for everyone mentioned in the message' do
- expect(Diaspora::Mentionable).to receive(:people_from_string).and_return(@people)
- @sm.mentions.delete_all
- @sm.create_mentions
- expect(@sm.mentions(true).map{|m| m.person}.to_set).to eq(@people.to_set)
+ describe "#create_mentions" do
+ it "creates a mention for everyone mentioned in the message" do
+ status_message
+ expect(Diaspora::Mentionable).to receive(:people_from_string).and_return(people)
+ status_message.mentions.delete_all
+ status_message.create_mentions
+ expect(status_message.mentions(true).map(&:person).to_set).to eq(people.to_set)
end
- it 'does not barf if it gets called twice' do
- @sm.create_mentions
+ it "does not barf if it gets called twice" do
+ status_message.create_mentions
- expect{
- @sm.create_mentions
+ expect {
+ status_message.create_mentions
}.to_not raise_error
end
end
- describe '#mentioned_people' do
- it 'calls create_mentions if there are no mentions in the db' do
- @sm.mentions.delete_all
- expect(@sm).to receive(:create_mentions)
- @sm.mentioned_people
+ describe "#mentioned_people" do
+ it "calls create_mentions if there are no mentions in the db" do
+ status_message.mentions.delete_all
+ expect(status_message).to receive(:create_mentions)
+ status_message.mentioned_people
end
- it 'returns the mentioned people' do
- @sm.mentions.delete_all
- expect(@sm.mentioned_people.to_set).to eq(@people.to_set)
+ it "returns the mentioned people" do
+ status_message.mentions.delete_all
+ expect(status_message.mentioned_people.to_set).to eq(people.to_set)
end
- it 'does not call create_mentions if there are mentions in the db' do
- expect(@sm).not_to receive(:create_mentions)
- @sm.mentioned_people
+ it "does not call create_mentions if there are mentions in the db" do
+ expect(status_message).not_to receive(:create_mentions)
+ status_message.mentioned_people
end
end
describe "#mentions?" do
- it 'returns true if the person was mentioned' do
- expect(@sm.mentions?(@people[0])).to be true
+ it "returns true if the person was mentioned" do
+ expect(status_message.mentions?(people[0])).to be true
end
- it 'returns false if the person was not mentioned' do
- expect(@sm.mentions?(FactoryGirl.build(:person))).to be false
+ it "returns false if the person was not mentioned" do
+ expect(status_message.mentions?(FactoryGirl.build(:person))).to be false
end
end
describe "#notify_person" do
- it 'notifies the person mentioned' do
+ it "notifies the person mentioned" do
expect(Notification).to receive(:notify).with(alice, anything, anything)
- @sm.notify_person(alice.person)
+ status_message.notify_person(alice.person)
end
end
describe "#filter_mentions" do
- it 'calls Diaspora::Mentionable#filter_for_aspects' do
+ it "calls Diaspora::Mentionable#filter_for_aspects" do
msg = FactoryGirl.build(:status_message_in_aspect)
msg_txt = msg.raw_message
@@ -233,222 +227,240 @@ STR
end
describe "#nsfw" do
- it 'returns MatchObject (true) if the post contains #nsfw (however capitalised)' do
- status = FactoryGirl.build(:status_message, :text => "This message is #nSFw")
+ it "returns MatchObject (true) if the post contains #nsfw (however capitalised)" do
+ status = FactoryGirl.build(:status_message, text: "This message is #nSFw")
expect(status.nsfw).to be_truthy
end
- it 'returns nil (false) if the post does not contain #nsfw' do
- status = FactoryGirl.build(:status_message, :text => "This message is #sFW")
+ it "returns nil (false) if the post does not contain #nsfw" do
+ status = FactoryGirl.build(:status_message, text: "This message is #sFW")
expect(status.nsfw).to be false
end
end
- describe 'tags' do
+ describe "tags" do
before do
@object = FactoryGirl.build(:status_message)
end
- it_should_behave_like 'it is taggable'
+ it_should_behave_like "it is taggable"
- it 'associates different-case tags to the same tag entry' do
+ it "associates different-case tags to the same tag entry" do
assert_equal ActsAsTaggableOn.force_lowercase, true
- msg_lc = FactoryGirl.build(:status_message, :text => '#newhere')
- msg_uc = FactoryGirl.build(:status_message, :text => '#NewHere')
- msg_cp = FactoryGirl.build(:status_message, :text => '#NEWHERE')
+ msg_lc = FactoryGirl.build(:status_message, text: "#newhere")
+ msg_uc = FactoryGirl.build(:status_message, text: "#NewHere")
+ msg_cp = FactoryGirl.build(:status_message, text: "#NEWHERE")
- msg_lc.save; msg_uc.save; msg_cp.save
+ msg_lc.save
+ msg_uc.save
+ msg_cp.save
tag_array = msg_lc.tags
expect(msg_uc.tags).to match_array(tag_array)
expect(msg_cp.tags).to match_array(tag_array)
end
- it 'should require tag name not be more than 255 characters long' do
- message = "##{'a' * (255+1)}"
- status_message = FactoryGirl.build(:status_message, :text => message)
+ it "should require tag name not be more than 255 characters long" do
+ message = "##{'a' * (255 + 1)}"
+ status_message = FactoryGirl.build(:status_message, text: message)
expect(status_message).not_to be_valid
end
end
describe "XML" do
- let(:message) { FactoryGirl.build(:status_message, text: "I hate WALRUSES!", author: @user.person) }
+ let(:message) { FactoryGirl.build(:status_message, text: "I hate WALRUSES!", author: user.person) }
let(:xml) { message.to_xml.to_s }
let(:marshalled) { StatusMessage.from_xml(xml) }
- it 'serializes the escaped, unprocessed message' do
+ it "serializes the escaped, unprocessed message" do
text = "[url](http://example.org)"
message.text = text
expect(xml).to include Builder::XChar.encode(text)
end
- it 'serializes the message' do
+ it "serializes the message" do
expect(xml).to include "I hate WALRUSES!"
end
- it 'serializes the author address' do
- expect(xml).to include(@user.person.diaspora_handle)
+ it "serializes the author address" do
+ expect(xml).to include(user.person.diaspora_handle)
end
- describe '.from_xml' do
- it 'marshals the message' do
+ describe ".from_xml" do
+ it "marshals the message" do
expect(marshalled.text).to eq("I hate WALRUSES!")
end
- it 'marshals the guid' do
+ it "marshals the guid" do
expect(marshalled.guid).to eq(message.guid)
end
- it 'marshals the author' do
+ it "marshals the author" do
expect(marshalled.author).to eq(message.author)
end
- it 'marshals the diaspora_handle' do
+ it "marshals the diaspora_handle" do
expect(marshalled.diaspora_handle).to eq(message.diaspora_handle)
end
end
- context 'with some photos' do
+ context "with some photos" do
before do
message.photos << FactoryGirl.build(:photo)
message.photos << FactoryGirl.build(:photo)
end
- it 'serializes the photos' do
+ it "serializes the photos" do
expect(xml).to include "photo"
expect(xml).to include message.photos.first.remote_photo_path
end
- describe '.from_xml' do
- it 'marshals the photos' do
+ describe ".from_xml" do
+ it "marshals the photos" do
expect(marshalled.photos.size).to eq(2)
end
- it 'handles existing photos' do
+ it "handles existing photos" do
message.photos.each(&:save!)
expect(marshalled).to be_valid
end
end
end
- context 'with a location' do
+ context "with a location" do
before do
message.location = FactoryGirl.build(:location)
end
- it 'serializes the location' do
+ it "serializes the location" do
expect(xml).to include "location"
expect(xml).to include "lat"
expect(xml).to include "lng"
end
describe ".from_xml" do
- it 'marshals the location' do
+ it "marshals the location" do
expect(marshalled.location).to be_present
end
end
end
- context 'with a poll' do
+ context "with a poll" do
before do
message.poll = FactoryGirl.build(:poll)
end
- it 'serializes the poll' do
+ it "serializes the poll" do
expect(xml).to include "poll"
expect(xml).to include "question"
expect(xml).to include "poll_answer"
end
describe ".from_xml" do
- it 'marshals the poll' do
+ it "marshals the poll" do
expect(marshalled.poll).to be_present
end
- it 'marshals the poll answers' do
+ it "marshals the poll answers" do
expect(marshalled.poll.poll_answers.size).to eq(2)
end
end
end
end
- describe '#after_dispatch' do
+ describe "#after_dispatch" do
before do
- @photos = [alice.build_post(:photo, :pending => true, :user_file=> File.open(photo_fixture_name)),
- alice.build_post(:photo, :pending => true, :user_file=> File.open(photo_fixture_name))]
-
+ @photos = [alice.build_post(:photo, pending: true, user_file: File.open(photo_fixture_name)),
+ alice.build_post(:photo, pending: true, user_file: File.open(photo_fixture_name))]
@photos.each(&:save!)
-
- @status_message = alice.build_post(:status_message, :text => "the best pebble.")
- @status_message.photos << @photos
-
+ @status_message = alice.build_post(:status_message, text: "the best pebble.")
+ @status_message.photos << @photos
@status_message.save!
alice.add_to_streams(@status_message, alice.aspects)
end
- it 'sets pending to false on any attached photos' do
+
+ it "sets pending to false on any attached photos" do
@status_message.after_dispatch(alice)
- expect(@photos.all?{|p| p.reload.pending}).to be false
+ expect(@photos.all? {|p| p.reload.pending }).to be false
end
- it 'dispatches any attached photos' do
+
+ it "dispatches any attached photos" do
expect(alice).to receive(:dispatch_post).twice
@status_message.after_dispatch(alice)
end
end
- describe 'oembed' do
- before do
- @youtube_url = "https://www.youtube.com/watch?v=3PtFwlKfvHI"
- @message_text = "#{@youtube_url} is so cool. so is this link -> https://joindiaspora.com"
- end
+ describe "oembed" do
+ let(:youtube_url) { "https://www.youtube.com/watch?v=3PtFwlKfvHI" }
+ let(:message_text) { "#{youtube_url} is so cool. so is this link -> https://joindiaspora.com" }
+ let(:status_message) { FactoryGirl.build(:status_message, text: message_text) }
- it 'should queue a GatherOembedData if it includes a link' do
- sm = FactoryGirl.build(:status_message, :text => @message_text)
+ it "should queue a GatherOembedData if it includes a link" do
+ status_message
expect(Workers::GatherOEmbedData).to receive(:perform_async).with(instance_of(Fixnum), instance_of(String))
- sm.save
+ status_message.save
end
- describe '#contains_oembed_url_in_text?' do
- it 'returns the oembed urls found in the raw message' do
- sm = FactoryGirl.build(:status_message, :text => @message_text)
- expect(sm.contains_oembed_url_in_text?).not_to be_nil
- expect(sm.oembed_url).to eq(@youtube_url)
+ describe "#contains_oembed_url_in_text?" do
+ it "returns the oembed urls found in the raw message" do
+ expect(status_message.contains_oembed_url_in_text?).not_to be_nil
+ expect(status_message.oembed_url).to eq(youtube_url)
end
end
end
- describe 'opengraph' do
- before do
- @ninegag_url = "http://9gag.com/gag/a1AMW16"
- @youtube_url = "https://www.youtube.com/watch?v=3PtFwlKfvHI"
- @message_text = "#{@ninegag_url} is so cool. so is this link -> https://joindiaspora.com"
- @oemessage_text = "#{@youtube_url} is so cool. so is this link -> https://joindiaspora.com"
- end
+ describe "opengraph" do
+ let(:ninegag_url) { "http://9gag.com/gag/a1AMW16" }
+ let(:youtube_url) { "https://www.youtube.com/watch?v=3PtFwlKfvHI" }
+ let(:message_text) { "#{ninegag_url} is so cool. so is this link -> https://joindiaspora.com" }
+ let(:oemessage_text) { "#{youtube_url} is so cool. so is this link -> https://joindiaspora.com" }
+ let(:status_message) { build(:status_message, text: message_text) }
- it 'should queue a GatherOpenGraphData if it includes a link' do
- sm = FactoryGirl.build(:status_message, :text => @message_text)
+ it "should queue a GatherOpenGraphData if it includes a link" do
+ status_message
expect(Workers::GatherOpenGraphData).to receive(:perform_async).with(instance_of(Fixnum), instance_of(String))
- sm.save
+ status_message.save
end
- describe '#contains_open_graph_url_in_text?' do
- it 'returns the opengraph urls found in the raw message' do
- sm = FactoryGirl.build(:status_message, :text => @message_text)
- expect(sm.contains_open_graph_url_in_text?).not_to be_nil
- expect(sm.open_graph_url).to eq(@ninegag_url)
+ describe "#contains_open_graph_url_in_text?" do
+ it "returns the opengraph urls found in the raw message" do
+ expect(status_message.contains_open_graph_url_in_text?).not_to be_nil
+ expect(status_message.open_graph_url).to eq(ninegag_url)
end
- it 'returns nil if the link is from trusted oembed provider' do
- sm = FactoryGirl.build(:status_message, :text => @oemessage_text)
- expect(sm.contains_open_graph_url_in_text?).to be_nil
- expect(sm.open_graph_url).to be_nil
+ it "returns nil if the link is from trusted oembed provider" do
+ status_message = FactoryGirl.build(:status_message, text: oemessage_text)
+ expect(status_message.contains_open_graph_url_in_text?).to be_nil
+ expect(status_message.open_graph_url).to be_nil
end
end
end
describe "validation" do
+ let(:status_message) { build(:status_message, text: @message_text) }
+
it "should not be valid if the author is missing" do
- sm = FactoryGirl.build(:status_message, text: @message_text)
- sm.author = nil
- expect(sm).not_to be_valid
+ status_message.author = nil
+ expect(status_message).not_to be_valid
+ end
+ end
+
+ describe ".coordinates" do
+ let(:status_message) { build(:status_message, text: @message_text) }
+
+ context "with location" do
+ let(:location) { build(:location) }
+
+ it "should deliver coordinates" do
+ status_message.location = location
+ expect(status_message.coordinates).to include(lat: location.lat, lng: location.lng)
+ end
+ end
+
+ context "without location" do
+ it "should deliver empty coordinates" do
+ expect(status_message.coordinates[:lat]).to be_nil
+ expect(status_message.coordinates[:lng]).to be_nil
+ end
end
end
end