Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
Add remote search
Browse files Browse the repository at this point in the history
  • Loading branch information
gdonald committed Oct 14, 2023
1 parent 2c04299 commit fefef20
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 26 deletions.
4 changes: 2 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ AllCops:
NewCops: enable
Style/Documentation:
Enabled: false
# RSpec/ExampleLength:
# Max: 7
RSpec/NestedGroups:
Max: 4
8 changes: 8 additions & 0 deletions app/controllers/remote_search_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class RemoteSearchController < ApplicationController
def index
@pages = RemoteSearchService.search(params[:q])
render layout: nil
end
end
3 changes: 3 additions & 0 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ import { application } from "./application"

import AutocompleteController from "./autocomplete_controller"
application.register("autocomplete", AutocompleteController)

import RemoteSearchController from "./remote_search_controller"
application.register("remote-search", RemoteSearchController)
25 changes: 25 additions & 0 deletions app/javascript/controllers/remote_search_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static targets = ['results']

static values = {
term: String
}

connect() {
let that = this

fetch(`/remote_search/?q=${this.termValue}`).then(
function (response) {
// console.log('response', response.text());
return response.text()
}).then(function (results) {
that.resultsTarget.innerHTML = results
return true
}).catch(function (error) {
console.warn('An error occured:', error)
return false
})
}
}
3 changes: 3 additions & 0 deletions app/models/remote_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

RemotePage = Struct.new(:title, :blurb, :content, :url)
6 changes: 1 addition & 5 deletions app/services/page_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ def initialize(params)
def search
return Page.none if q.blank?

pages = Page.search_by_term(q).page(page).per(10).without_count

pages = ServerSearchService.search(q) if pages.empty?

pages
Page.search_by_term(q).page(page).per(10).without_count
end
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module ServerSearchService
module RemoteSearchService
include Headers

def self.search(term) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
Expand All @@ -10,16 +10,27 @@ def self.search(term) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
address = server.server_addresses.first
return Page.none unless address

url = "https://#{address.value}/search?q=#{term}"
url = "#{scheme.name}://#{address.value}#{port}/api/search?q=#{term}"

response = HTTParty.get(url, { headers: })
json = JSON.parse(response.body)

pages = []
json['pages'].each do |page|
pages << Page.new(title: page['title'], blurb: page['blurb'], content: page['content'])
pages << RemotePage.new(title: page['title'], blurb: page['blurb'], content: page['content'])
end

pages
end

class << self
def scheme
name = Rails.env.production? ? 'https' : 'http'
Scheme.find_by(name:)
end

def port
Rails.env.production? ? '' : ':3000'
end
end
end
1 change: 1 addition & 0 deletions app/views/api/searches/show.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ json.pages @pages do |page|
json.title page.title
json.url page.url
json.blurb page.blurb
json.url page.url
end
json.next_page @pages.respond_to?(:next_page) ? path_to_next_page(@pages) : nil
15 changes: 15 additions & 0 deletions app/views/remote_search/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="container mx-auto mt-3 pb-5">
<% if @pages&.any? %>
<p>Search results for "<%= params[:q] %>":</p>

<% @pages.each do |page| %>
<article class="mt-4">
<h2 class="fs-5"><%= link_to page.title, page.url, class: 'text-decoration-none', target: '_blank' %></h2>
<p class="fs-6 pt-0 pb-0 page-link"><%= link_to page.url, page.url, class: 'text-decoration-none link-opacity-50', target: '_blank' %></p>
<p class="fs-6 pt-0"><%= page.blurb %></p>
</article>
<% end %>
<% else %>
<p>No remote search results found for "<%= params[:q] %>".</p>
<% end %>
</div>
4 changes: 3 additions & 1 deletion app/views/searches/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
<%= link_to_next_page @pages, 'Next Page' %>
</div>
<% else %>
<p>No search results found for "<%= params[:q] %>"</p>
<p data-controller="remote-search"
data-remote-search-term-value="<%= params[:q] %>"
data-remote-search-target="results">No local search results found for "<%= params[:q] %>". Searching the network...</p>
<% end %>
</div>
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
resource :search, only: %i[show]
end

resources :remote_search, only: %i[index]

resource :search, only: %i[show] do
get :autocomplete, on: :collection
end
Expand Down
12 changes: 12 additions & 0 deletions spec/requests/remote_search_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'RemoteSearches' do
describe 'GET /index' do
it 'returns http success' do
get '/remote_search'
expect(response).to have_http_status(:success)
end
end
end
10 changes: 0 additions & 10 deletions spec/services/page_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,4 @@
expect(result).to eq([page])
end
end

context 'when params are present and no local results' do
let(:params) { { q: 'test' } }

it 'calls ServerSearchService' do
allow(ServerSearchService).to receive(:search)
result
expect(ServerSearchService).to have_received(:search).with('test')
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require 'rails_helper'

RSpec.describe ServerSearchService do
RSpec.describe RemoteSearchService do
subject(:klass) { described_class }

describe '.search' do
Expand All @@ -27,15 +27,33 @@
context 'with a server with an address' do
let(:body) { pages.to_json }

before { create(:server_address) }
before do
create(:server_address)
create(:scheme, :http)
end

it 'returns an empty array' do
stub_request(:get, 'https://example.com/search?q=term')
it 'returns an array' do
stub_request(:get, 'http://example.com:3000/api/search?q=term')
.with(headers: { 'User-Agent' => 'ELDAC/1.0 (https://eldac.io)' })
.to_return(status: 200, body:, headers: {})

expect(result.first.title).to eq('title')
end

context 'with a production environment' do
before do
allow(Rails.env).to receive(:production?).and_return(true)
create(:scheme)
end

it 'returns an array' do
stub_request(:get, 'https://example.com/api/search?q=term')
.with(headers: { 'User-Agent' => 'ELDAC/1.0 (https://eldac.io)' })
.to_return(status: 200, body:, headers: {})

expect(result.first.title).to eq('title')
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/system/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
click_button(id: 'search')
end

expect(page).to have_css('p', text: 'No search results found for "test"')
expect(page).to have_css('p', text: 'No remote search results found for "test"')
end
end

Expand Down

0 comments on commit fefef20

Please sign in to comment.