Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1c3444c
Merge pull request #1 from thepracticaldev/master
sarthology Dec 6, 2019
b440e53
Feature 🚀 : Ability to delete messages in chat channels
sarthology Dec 9, 2019
e6f8d29
Minor Bug 🐞: Show message action only for current user
sarthology Dec 9, 2019
e796764
Test cases added
sarthology Dec 9, 2019
bb01218
Bug 🐞: Update message id for receiver
sarthology Dec 9, 2019
8d402cf
Refactoring🛠: Message controller refactoring
sarthology Dec 9, 2019
a8bd27c
Test Cases📝 : Specs for Delete message added
sarthology Dec 10, 2019
bb805ed
Feature 🚀 : Ability to edit messages
sarthology Dec 16, 2019
481f0db
Test Cases📝 : Specs for Edit message added
sarthology Dec 16, 2019
1b4275b
Merge pull request #2 from SkynoxTech/feature/ability_to_delete_and_e…
sarthology Dec 16, 2019
1421c0f
Merge remote-tracking branch 'upstream/master'
sarthology Dec 19, 2019
71c6582
Merge remote-tracking branch 'upstream/master'
sarthology Dec 21, 2019
a67f57c
Merge remote-tracking branch 'origin/master'
sarthology Dec 21, 2019
7a23050
Merge conflict handled
sarthology Dec 25, 2019
e2ba1b4
Merge remote-tracking branch 'upstream/master'
sarthology Dec 25, 2019
ef7d1f8
merge conflicts handled
sarthology Jan 12, 2020
b8d4599
Merge branch 'master' of github.com:thepracticaldev/dev.to
sarthology Jan 18, 2020
8f1e9fe
Merge remote-tracking branch 'upstream/master'
sarthology Jan 21, 2020
fb32bbb
Merge branch 'master' of github.com:thepracticaldev/dev.to
sarthology Jan 27, 2020
eebd53c
Merge remote-tracking branch 'upstream/master'
sarthology Feb 2, 2020
bf4cc32
Merge remote-tracking branch 'upstream/master'
sarthology Mar 3, 2020
53fdcdc
Added functionality for preview medium
nitinvupk Mar 26, 2020
11eda6f
Added spec for previre medium
nitinvupk Mar 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Envfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ variable :REDIS_SIDEKIQ_URL, :String, default: "redis://localhost:6379"
# Elasticsearch
variable :ELASTICSEARCH_URL, :String, default: "http://localhost:9200"

# env
variable :MEDIUM_DOMIAN, :String, default: "https://medium.com/"

################################################
############## 3rd Party Services ##############
################################################
Expand Down Expand Up @@ -182,4 +185,5 @@ group :production do

# Heroku
variable :HEROKU_APP_URL, :String # practicaldev.herokuapp.com
variable :MEDIUM_DOMIAN, :String, default: "https://medium.com/"
end
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ gem "oj", "~> 3.10" # JSON parser and object serializer
gem "omniauth", "~> 1.9" # A generalized Rack framework for multiple-provider authentication
gem "omniauth-github", "~> 1.3" # OmniAuth strategy for GitHub
gem "omniauth-twitter", "~> 1.4" # OmniAuth strategy for Twitter
gem "opengraph_parser"
gem "pg", "~> 1.2" # Pg is the Ruby interface to the PostgreSQL RDBMS
gem "puma", "~> 4.3" # Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
gem "pundit", "~> 2.1" # Object oriented authorization for Rails applications
Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,9 @@ GEM
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
opengraph_parser (0.2.3)
addressable
nokogiri
orm_adapter (0.5.0)
os (1.0.1)
parallel (1.19.1)
Expand Down Expand Up @@ -921,6 +924,7 @@ DEPENDENCIES
omniauth (~> 1.9)
omniauth-github (~> 1.3)
omniauth-twitter (~> 1.4)
opengraph_parser
parallel_tests (~> 2.31)
pg (~> 1.2)
pry (~> 0.12)
Expand Down
3 changes: 3 additions & 0 deletions app/models/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,11 @@ def append_rich_links(html)
#{user.name}
</h1>
</a>".html_safe
elsif (medium = PreviewMediumService.call(anchor))
html += medium.rich_link.html_safe
end
end

html
end

Expand Down
51 changes: 51 additions & 0 deletions app/services/preview_medium_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
class PreviewMediumService
def initialize(link)
@href = link["href"]
end

def self.call(link)
new(link).call
end

def call
return unless valid_url?

response = send_request
return unless response

@medium = create_attributes(response)
self
end

def rich_link
return "" unless valid_url?

"<a href='#{medium.url}'
class='chatchannels__richlink'
target='_blank' data-content='sidecar-medium'>
#{"<div class='chatchannels__richlinkmainimage' style='background-image:url(" + medium.image_url + ")' data-content='sidecar-medium' ></div>" if medium.image_url.present?}
<h1 data-content='sidecar-medium'>#{medium.title}</h1>
<h4 data-content='sidecar-medium'>#{medium.description}</h4>"
end

private

attr_reader :href, :medium

def valid_url?
href.include?(ApplicationConfig["MEDIUM_DOMIAN"]) && href.split("/")[4].present?
end

def send_request
OpenGraph.new(href)
end

def create_attributes(response)
OpenStruct.new(
url: response.url,
image_url: response.images[0],
title: response.title,
description: response.description,
)
end
end
18 changes: 18 additions & 0 deletions spec/models/message_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
let(:chat_channel) { create(:chat_channel) }
let(:message) { create(:message, user: user) }
let(:random_word) { Faker::Lorem.word }
let(:medium_url) { "https://medium.com/@jpsmithalt/hold-the-line-17231c48ff17" }

describe "validations" do
context "with automatic validations" do
Expand Down Expand Up @@ -73,6 +74,23 @@
expect(message.message_html).not_to include("data-content")
end

it "creates rich link with non-rich link for medium" do
stub_request(:get, medium_url).
with(
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"User-Agent" => "Ruby"
},
).
to_return(status: 200, body: "medium article", headers: {})

message.message_markdown = medium_url
message.validate!

expect(message.message_html).to include("data-content")
end

it "creates mention if user exists" do
message.message_markdown = "Hello @#{user.username}"
message.validate!
Expand Down
82 changes: 82 additions & 0 deletions spec/services/preview_medium_spec_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
require "rails_helper"

RSpec.describe PreviewMediumService, type: :service do
describe "service methods" do
let(:valid_medium_url) { "https://medium.com/@sfchronicle/why-mark-zuckerberg-should-step-down-as-facebook-ceo-795410ef12eb" }
let(:invalid_medium_url) { "https://dev.to/nas5w/first-class-functions-in-javascript-5dj2" }
let(:object) { described_class.call("href" => valid_medium_url) }

before do
stub_request(:get, valid_medium_url).
with(
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"User-Agent" => "Ruby"
},
).
to_return(status: 200, body: "medium", headers: {})
end

describe "class_methods" do
it ".call" do
expect(object).to be_a described_class
end
end

describe "instance_methods" do
context "with #call" do
it "return nil without valid_url" do
allow(object).to receive(:valid_url?).and_return(false)
expect(object.call).to be_nil
end

it "return nil with invalid response" do
allow(object).to receive(:send_request).and_return(nil)
expect(object.call).to be_nil
end

it "return object with sucess response" do
expect(object.call).to be_a described_class
end
end

context "with #valid_url" do
it "with valid url" do
expect(object.send(:valid_url?)).to be_truthy
end

it "with invalid url" do
allow(object).to receive(:href).and_return(invalid_medium_url)
expect(object.send(:valid_url?)).to be_falsy
end
end

context "with #rich_link" do
it "return with invalid_url" do
allow(object).to receive(:valid_url?).and_return(false)
expect(object.rich_link).to eq("")
end

it "return with valid_url" do
expect(object.rich_link).to include("sidecar-medium")
expect(object.rich_link).to include("chatchannels__richlink")
end
end

it "#create_attributes" do
response = OpenStruct.new(
url: valid_medium_url,
images: ["https://miro.medium.com/max/920/0*x6DKkfEFloE-Lgiw.jpg"],
title: "Why Mark Zuckerberg Should Step Down as Facebook CEO",
description: "A shift in the role of CEO Mark Zuckerberg might help address",
)
res = object.send(:create_attributes, response)
expect(res.url).to eq(response.url)
expect(res.image_url).to eq(response.images[0])
expect(res.title).to eq(response.title)
expect(res.description).to eq(response.description)
end
end
end
end