From c041ae596fa5b3d584afde3beb2f24e678fea7cf Mon Sep 17 00:00:00 2001
From: Joerg Reichert <de.abg.reichert.joerg@googlemail.com>
Date: Sun, 1 Jan 2017 13:41:28 +0100
Subject: [PATCH] #12 - fixed rspec tests and add some more tests

---
 app/controllers/search_controller.rb | 38 ++++++++++-----
 app/views/search/index.html.slim     |  9 ++--
 spec/features/basic_search_spec.rb   | 73 ++++++++++++++++++++++++----
 3 files changed, 94 insertions(+), 26 deletions(-)

diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 8653b7c..5948e6e 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -26,22 +26,34 @@ class SearchController < ApplicationController
     @papers = @response.page(params[:page]).results
     @sub = Hash.new
     @papers.each do |paper|
-      @sub_search_definition = Elasticsearch::DSL::Search.search do
-        query do
-          query_string do
-        	query "*" + (paper.reference.start_with?("VI-") ? paper.reference.split("-")[2] : paper.reference.split("-")[1]) + "*"
-        	fields ["reference"]
+      unless paper.reference.nil? && paper.reference.contains("-")
+        segments = paper.reference.split("-")
+        id = (paper.reference.start_with?("VI-") && segments.count > 2 ?
+          segments[2] : segments[1])
+        escaped_chars = Regexp.escape('\\+-*:()[]{}&!?^|\/')
+        sanitized_id = id.gsub(/([#{escaped_chars}])/, '\\\\\1')
+        ['AND', 'OR', 'NOT'].each do |reserved|
+          escaped_reserved = reserved.split('').map { |c| "\\#{c}" }.join('')
+          sanitized_id = sanitized_id.gsub('/\s*\b(#{reserved.upcase})\b\s*/',
+            " #{escaped_reserved} ")
+        end
+        @sub_search_definition = Elasticsearch::DSL::Search.search do
+          query do
+            query_string do
+          	  query "*" + sanitized_id + "*"
+              fields ["reference"]
+            end
+          end
+
+          sort do
+            by :published_at, order: 'asc'
+            by :reference, order: 'asc'
           end
         end
-
-        sort do
-          by :published_at, order: 'asc'
-          by :reference, order: 'asc'
-        end 
+        @sub_papers = Paper.search(@sub_search_definition)
+        @sub[paper.reference] = @sub_papers
       end
-      @sub_papers = Paper.search(@sub_search_definition)
-      @sub[paper.reference] = @sub_papers
-    end  
+    end
     @paper_type_facets = extract_facets('paper_types')
     @originator_facets = extract_facets('originators')
   end
diff --git a/app/views/search/index.html.slim b/app/views/search/index.html.slim
index ac1d78d..41bd921 100644
--- a/app/views/search/index.html.slim
+++ b/app/views/search/index.html.slim
@@ -13,10 +13,11 @@ div
       li.search-result
         article
           h4 = doc.name
-          ul
-            - @sub[doc.reference].each do |sub|
-              li class="#{'current' if sub.reference == doc.reference}"
-                div = link_to "#{l sub.published_at.to_date}: #{sub.paper_type} von #{sub.originator.join(", ")}", sub.url, target: '_blank'
+          - if @sub[doc.reference]
+            ul
+              - @sub[doc.reference].each do |sub|
+                li class="#{'current' if sub.reference == doc.reference}"
+                  div = link_to "#{l sub.published_at.to_date}: #{sub.paper_type} von #{sub.originator.join(", ")}", sub.url, target: '_blank'
               
 
 div#pagination
diff --git a/spec/features/basic_search_spec.rb b/spec/features/basic_search_spec.rb
index af46c9a..a78aba2 100644
--- a/spec/features/basic_search_spec.rb
+++ b/spec/features/basic_search_spec.rb
@@ -1,4 +1,5 @@
 require 'rails_helper'
+require 'pp'
 
 RSpec.feature "Basic search", type: :feature, elasticsearch: true do
 
@@ -46,11 +47,19 @@ RSpec.feature "Basic search", type: :feature, elasticsearch: true do
   scenario "Search results have basic information" do
     visit search_path body: "leipzig"
     paper = @papers.first
-    result = page.find("li.search-result", match: :first)
-    expect(result).to have_link(paper.name, href: paper.url)
-    expect(result).to have_css("span.paper_type", text: paper.paper_type)
-    expect(result).to have_css("span.originator", text: paper.originator)
-    expect(result).to have_css("span.published", text: I18n.l(paper.published_at.to_date))
+    resultEntry = page.find("li.search-result", match: :first)
+    expect(resultEntry).to have_content(paper.name)
+
+    resultSubEntry = resultEntry.find("li.current", match: :first)
+    linkName = getLinkName(paper)
+    expect(resultSubEntry).to have_link(linkName, href: paper.url)
+  end
+
+  def getLinkName(paper)
+    dateStr = I18n.l(paper.published_at.to_date)
+    originatorStr = (paper.originator.kind_of?(Array) ?
+      paper.originator.join(", ") : paper.originator)
+    return "#{dateStr}: #{paper.paper_type} von #{originatorStr}"
   end
 
   scenario "Finds papers by name" do
@@ -58,8 +67,12 @@ RSpec.feature "Basic search", type: :feature, elasticsearch: true do
     Paper.__elasticsearch__.refresh_index!
     visit search_path body: "leipzig", paper_search: {query: "Opendata"}
     expect(page).to have_content("1 Dokument in der Datenbank")
-    result = page.find("li.search-result", match: :first)
-    expect(result).to have_link(paper.name, href: paper.url)
+    resultEntry = page.find("li.search-result", match: :first)
+    expect(resultEntry).to have_content(paper.name)
+
+    resultSubEntry = resultEntry.find("li.current", match: :first)
+    linkName = getLinkName(paper)
+    expect(resultSubEntry).to have_link(linkName, href: paper.url)
   end
 
   scenario "Finds papers by content" do
@@ -70,8 +83,50 @@ RSpec.feature "Basic search", type: :feature, elasticsearch: true do
     Paper.__elasticsearch__.refresh_index!
     visit search_path body: "leipzig", paper_search: {query: "Verwaltungsdokumente"}
     expect(page).to have_content("1 Dokument in der Datenbank")
-    result = page.find("li.search-result", match: :first)
-    expect(result).to have_link(paper.name, href: paper.url)
+    resultEntry = page.find("li.search-result", match: :first)
+    expect(resultEntry).to have_content(paper.name)
+
+    resultSubEntry = resultEntry.find("li.current", match: :first)
+    linkName = getLinkName(paper)
+    expect(resultSubEntry).to have_link(linkName, href: paper.url)
   end
 
+  scenario "Papers with common reference id in search result ordered by date" do
+    mainPaper = FactoryGirl.create(:paper, published_at: '2016-12-19T19:00:00',
+      name: "Opendata als default", reference: "VI-0815")
+    newPaper = FactoryGirl.create(:paper, published_at: '2016-12-23T12:00:00',
+        name: "Opendata als optional", reference: "VI-0815-ÄA-01")
+    Paper.__elasticsearch__.refresh_index!
+    visit search_path body: "leipzig", paper_search: {query: "default"}
+    expect(page).to have_content("1 Dokument in der Datenbank")
+    resultEntry = page.find("li.search-result", match: :first)
+    expect(resultEntry).to have_content(mainPaper.name)
+
+    resultSubEntry1 = resultEntry.find("li.current", match: :first)
+    linkName1 = getLinkName(mainPaper)
+    expect(resultSubEntry1).to have_link(linkName1, href: mainPaper.url)
+
+    resultSubEntries = resultEntry.find("ul").all("li")
+    linkName2 = getLinkName(newPaper)
+    expect(resultSubEntries[1]).to have_link(linkName2, href: newPaper.url)
+  end
+
+  scenario "Papers with common reference id in search result ordered by ref" do
+    mainPaper = FactoryGirl.create(:paper, published_at: '2016-12-19T19:00:00',
+      name: "Opendata als default", reference: "VI-0815")
+    newPaper1 = FactoryGirl.create(:paper, published_at: '2016-12-23T12:00:00',
+        name: "Opendata als optional", reference: "VI-0815-ÄA-02")
+    newPaper2 = FactoryGirl.create(:paper, published_at: '2016-12-23T12:00:00',
+            name: "Opendata als optional", reference: "VI-0815-ÄA-01")
+    Paper.__elasticsearch__.refresh_index!
+    visit search_path body: "leipzig", paper_search: {query: "default"}
+    expect(page).to have_content("1 Dokument in der Datenbank")
+    resultEntry = page.find("li.search-result", match: :first)
+
+    resultSubEntries = resultEntry.find("ul").all("li")
+    linkName1 = getLinkName(newPaper1)
+    expect(resultSubEntries[2]).to have_link(linkName1, href: newPaper1.url)
+    linkName2 = getLinkName(newPaper2)
+    expect(resultSubEntries[1]).to have_link(linkName2, href: newPaper2.url)
+  end
 end