<commit_before># coding: utf-8

require 'rails_helper'

describe 'Search page', js: true do
  let (:now) { DateTime.now }
  it "works" do
    dances = 12.times.map {|i| FactoryGirl.create(:dance, title: "Dance #{i}.", created_at: now - i.days)}
    visit(s_path)
    dances.each_with_index do |dance, i|
      to_probably = i < 10 ? :to : :to_not
      expect(page).send to_probably, have_link(dance.title, href: dance_path(dance))
      expect(page).send to_probably, have_link(dance.choreographer.name, href: choreographer_path(dance.choreographer_id))
      expect(page).send to_probably, have_link(dance.user.name, href: user_path(dance.user_id))
      expect(page).send to_probably, have_text(dance.created_at.localtime.strftime("%-m/%-d/%Y"))
    end
  end

  describe 'pagination' do
    def have_turn_page_button(*args)
      have_css(turn_page_button_css(*args))
    end

    def turn_page_button_css(label, disabled=false)
      "button[data-testid=#{label.inspect}]#{disabled ? '[disabled]' : ''}"
    end

    let! (:dances) { 52.times.map {|i| FactoryGirl.create(:dance, title: "dance-#{i}.", created_at: now - i.hours)} }
    it "turning pages" do
      visit(s_path)
      # first page
      10.times {|i| expect(page).to have_link("dance-#{i}.")}
      expect(page).to have_text('Showing 1 to 10 of 52 dances')
      expect(page).to have_turn_page_button('<<', disabled: true)# have_css('button[data-testid="<<"][disabled]')
      expect(page).to have_turn_page_button('<', disabled: true)
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      page.find(turn_page_button_css('>')).click
      # second page
      10.times {|i| expect(page).to have_link("dance-#{i+10}.")}
      expect(page).to have_text('Showing 11 to 20 of 52 dances')
      expect(page).to have_turn_page_button('<<')
      expect(page).to have_turn_page_button('<')
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      page.find(turn_page_button_css('<')).click
      # first page
      10.times {|i| expect(page).to have_link("dance-#{i}.")}
      expect(page).to have_text('Showing 1 to 10 of 52 dances')
      expect(page).to have_turn_page_button('<<', disabled: true)
      expect(page).to have_turn_page_button('<', disabled: true)
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      # third page via numeric input
      find('.page-number-entry').fill_in(with: '3') # third page
      10.times {|i| expect(page).to have_link("dance-#{i+20}.")}
      expect(page).to have_text('Showing 21 to 30 of 52 dances')
      expect(page).to have_turn_page_button('<<')
      expect(page).to have_turn_page_button('<')
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      page.find(turn_page_button_css('>>')).click
      # last (partial) page
      2.times {|i| expect(page).to have_link("dance-#{i+50}.")}
      expect(page).to have_text('Showing 51 to 52 of 52 dances')
      expect(page).to have_turn_page_button('<<')
      expect(page).to have_turn_page_button('<')
      expect(page).to have_turn_page_button('>', disabled: true)
      expect(page).to have_turn_page_button('>>', disabled: true)
      page.find(turn_page_button_css('<<')).click
      # first page
      10.times {|i| expect(page).to have_link("dance-#{i}.")}
      expect(page).to have_text('Showing 1 to 10 of 52 dances')
      expect(page).to have_turn_page_button('<<', disabled: true)
      expect(page).to have_turn_page_button('<', disabled: true)
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
    end

    it "page size select menu" do
      visit(s_path)
      expect(page).to have_text("Showing 1 to 10 of 52 dances.")
      select('30')
      expect(page).to have_text("Showing 1 to 30 of 52 dances.")
      page.find(turn_page_button_css('>')).click
      expect(page).to have_text("Showing 31 to 52 of 52 dances.")
      (dances.length-30).times do |i|
        expect(page).to have_link("dance-#{i+30}.")
      end
    end
  end

  describe 'columns' do
    let (:dances) {[:dance, :box_the_gnat_contra, :call_me].map {|d| FactoryGirl.create(d)}}
    it "Clicking vis toggles buttons cause columns to disappear" do
      dances
      visit(s_path)
      %w[Title Choreographer Formation Hook User Entered].each do |col|
        expect(page).to have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-active', text: col)
        expect(page).to_not have_css('button.toggle-vis-inactive', text: col)
        click_button col
        expect(page).to_not have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-inactive', text: col)
        expect(page).to_not have_css('button.toggle-vis-active', text: col)
        click_button col
        expect(page).to have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-active', text: col)
        expect(page).to_not have_css('button.toggle-vis-inactive', text: col)
      end
      %w[Updated Sharing Figures].each do |col|
        expect(page).to_not have_css('.dances-table-react th', text: col)
        expect(page).to_not have_css('button.toggle-vis-active', text: col)
        expect(page).to  have_css('button.toggle-vis-inactive', text: col)
        click_button col
        expect(page).to have_css('.dances-table-react th', text: col)
        expect(page).to_not have_css('button.toggle-vis-inactive', text: col)
        expect(page).to have_css('button.toggle-vis-active', text: col)
        click_button col
        expect(page).to_not have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-inactive', text: col)
        expect(page).to_not have_css('button.toggle-vis-active', text: col)
      end
    end

    it 'published column cells' do
      with_login do |user|
        dances.each_with_index do |dance, i|
          publish = [:off, :sketchbook, :all][i]
          publish_string = ['private', 'sketchbook', 'everywhere'][i]
          dance.update!(publish: publish, user: user)
          visit(s_path)
          click_button 'Sharing'
          expect(page).to have_css('tr', text: /#{dance.title}.*#{publish_string}/)
        end
      end
    end

    describe 'matching figures column' do
      it 'whole dance' do
        dances
        visit(s_path)
        expect(page).to_not have_css(:th, text: "Figures")
        expect(page).to_not have_content('whole dance')
        click_button 'Figures'
        expect(page).to have_css(:th, text: "Figures") # js wait
        expect(page).to have_content('whole dance', count: 3)
      end

      it 'some matches prints figures' do
        # TODO: update how we pass the filter when there's a user-facing way to send figure queries
        # 4NOW: stub the controller, heh heh -dm 01-30-2020
        expect_any_instance_of(Api::V1::DancesController).to receive(:filter).and_return(['figure', 'circle'])
        # mock
        dances
        visit(s_path)
        click_button 'Figures'
        expect(page).to have_css('tr', text: /The Rendevouz.*\n?circle left 4 places\ncircle left 3 places/)
        expect(page).to have_css('tr', text: /Call Me.*\n?circle left 3 places/)
      end
    end
  end

  it "sentence displays how many search results match" do
    dbsize = 12
    dbsize.times.map {|i| FactoryGirl.create(:dance, created_at: now - i.hours)}
    visit(s_path)
    expect(page).to have_content("Showing 1 to 10 of #{dbsize} dances.")
  end

  describe "sorting" do
    it "clicking a header displays that column in descending order" do
      shuffled_ints = [7, 0, 10, 8, 9, 2, 11, 6, 3, 5, 1, 4]
      dances = shuffled_ints.map.with_index {|shuffled_int, i|
        FactoryGirl.create(:dance, title: "dance-#{shuffled_int.to_s.rjust(2, '0')}", created_at: now - i.hours)
      }
      dances_sorted = dances.dup.sort_by(&:title)
      visit(s_path)
      dances.each_with_index do |dance, i|
        expect(page).send(i < 10 ? :to : :to_not, have_text(dance.title))
      end
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      unsorted_dances_titles_regex = Regexp.new(dances.take(10).map(&:title).join('.*\n'))
      expect(page).to have_text(unsorted_dances_titles_regex)

      # first click makes it sort descending
      find('th', text: 'Title').click
      expect(page).to have_css('th .glyphicon-sort-by-attributes')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      dances_sorted.each_with_index do |dance, i|
        expect(page).send(i < 10 ? :to : :to_not, have_text(dance.title))
      end
      # we see we have the dances, but do we have them in order? dance-00, dance-01, ... dance-09
      first_ten_dances_titles_regex = Regexp.new(dances_sorted.take(10).map(&:title).join('.*\n'))
      expect(page).to have_text(first_ten_dances_titles_regex)

      # second click makes it sort ascending
      find('th', text: 'Title').click
      expect(page).to have_css('th .glyphicon-sort-by-attributes-alt')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      dances_sorted.each_with_index do |dance, i|
        expect(page).send(i >= dances.length-10 ? :to : :to_not, have_text(dance.title))
      end
      # we see we have the dances, but do we have them in order? dance-12, dance-11, ... dance-02
      last_ten_dances_titles_regex = Regexp.new(dances_sorted.reverse.take(10).map(&:title).join('.*\n'))
      expect(page).to have_text(last_ten_dances_titles_regex)

      # third click returns to default sort (which is by descending created_at)
      find('th', text: 'Title').click
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      dances.each_with_index do |dance, i|
        expect(page).send(i < 10 ? :to : :to_not, have_text(dance.title))
      end
      expect(page).to have_text(unsorted_dances_titles_regex)
    end

    it "no weird monkey business with client side sorting" do
      titles = ['40 Years of Penguin Pam', "A Crafty Wave", "24th of June"]
      dances = titles.map {|title| FactoryGirl.create(:dance, title: title)}
      titles_sorted = titles.dup.sort
      visit(s_path)
      find('th', text: 'Title').click
      expect(page).to have_text(Regexp.new(titles_sorted.join('.*\n')))
    end

    it "you can't sort by matching figures" do
      dances = [:dance, :box_the_gnat_contra, :call_me].each_with_index.map do |t, i|
        FactoryGirl.create(t, created_at: now - i.hours)
      end
      the_ordered_regexp = Regexp.new(dances.map(&:title).join('(?:.*\n)+'))
      visit(s_path)
      click_button 'Figures'
      expect(page).to have_content(the_ordered_regexp) # order is time-sorted
      find('th', text: 'Figures').click
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      expect(page).to have_content(the_ordered_regexp) # order is still time-sorted
    end

    it "sorting all columns (except matching figure) does not give error" do
      dances = [:dance, :box_the_gnat_contra, :call_me].each_with_index.map do |t, i|
        FactoryGirl.create(t, created_at: now - i.hours)
      end
      visit(s_path)
      columns = page.find_all(".toggle-vis-active").to_a + page.find_all(".toggle-vis-inactive").to_a
      column_names = columns.map(&:text)
      column_names_not_to_check = ['Figures']
      column_names_checked = column_names - column_names_not_to_check
      column_names_checked.each do |column_name|
        unless has_css?('.toggle-vis-active', text: column_name)
          click_button(column_name)
        end
        th = find('.dance-table-th', text: column_name)
        expect(th).to have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes-alt')
        th.click
        expect(th).to have_css('.glyphicon-sort-by-attributes')
        expect(th).to_not have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes-alt')
        th.click
        expect(th).to have_css('.glyphicon-sort-by-attributes-alt')
        expect(th).to_not have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes')
        th.click
        expect(th).to have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes-alt')
      end
    end
  end

  describe "ez-filters" do
    describe "choreographer" do
      let(:dances) { [:dance, :box_the_gnat_contra, :call_me].map {|name| FactoryGirl.create(name)} }

      it "works" do
        call_me = dances.last
        dont_call_me = dances[0, dances.length-2]
        visit(s_path)
        find('.ez-choreographer-filter').fill_in(with: call_me.choreographer)
        dont_call_me.each do |dance|
          expect(page).to_not have_content(dance.title)
        end
      end
    end

    describe "verified" do
      let! (:dances) do
        %w(unverified yaverified verified-by-me).map {|s| FactoryGirl.create(:dance, title: s)}
      end
      let (:user) { FactoryGirl.create(:user) }
      let (:verified) { FactoryGirl.create(:tag, :verified) }
      let! (:dut_somebody_else) { FactoryGirl.create(:dut, tag: verified, dance: dances[1]) }
      let! (:dut_by_me) { FactoryGirl.create(:dut, tag: verified, dance: dances[2], user: user) }
      let (:unverified_dance) { dances[0] }
      let (:verified_dance) { dances[1] }
      let (:verified_by_me_dance) { dances[2] }

      it "'verified' and 'not verified' checkboxes work" do
        visit(s_path)
        expect_dances(verified: true, not_verified: false) # the default
        check 'ez-not-verified'
        expect_dances(verified: true, not_verified: true)
        uncheck 'ez-verified', match: :prefer_exact
        expect_dances(verified: false, not_verified: true)
        uncheck 'ez-not-verified'
        expect_dances(verified: false, not_verified: false)
        check 'ez-verified', match: :prefer_exact
        expect_dances(verified: true, not_verified: false)
      end

      it "'verified by me' and 'not verified by me' checkboxes work" do
        with_login(user: user) do
          visit(s_path)
          expect_dances(verified: true) # the default
          uncheck 'ez-verified', match: :prefer_exact
          expect_dances()
          check 'ez-not-verified-by-me'
          expect_dances(not_verified_by_me: true)
          check 'ez-verified-by-me'
          expect_dances(verified_by_me: true, not_verified_by_me: true)
          uncheck 'ez-not-verified-by-me'
          expect_dances(verified_by_me: true)
          uncheck 'ez-verified-by-me'
          expect_dances()
        end
      end

      def expect_dances(verified: false,
                        not_verified: false,
                        verified_by_me: false,
                        not_verified_by_me: false)
        expect(page).send(not_verified || not_verified_by_me ? :to : :to_not, have_content(unverified_dance.title))
        expect(page).send(verified || not_verified_by_me ? :to : :to_not, have_content(verified_dance.title))
        expect(page).send(verified || verified_by_me ? :to : :to_not, have_content(verified_by_me_dance.title))
      end

      it "verified by me and not verified by me are disabled when not logged in"
    end
  end
end<commit_msg>fix spec/features/welcome/search_spec.rb<commit_after># coding: utf-8

require 'rails_helper'

describe 'Search page', js: true do
  let (:now) { DateTime.now }
  it "works" do
    dances = 12.times.map {|i| FactoryGirl.create(:dance, title: "Dance #{i}.", created_at: now - i.days)}
    tag_all_dances
    visit(s_path)
    dances.each_with_index do |dance, i|
      to_probably = i < 10 ? :to : :to_not
      expect(page).send to_probably, have_link(dance.title, href: dance_path(dance))
      expect(page).send to_probably, have_link(dance.choreographer.name, href: choreographer_path(dance.choreographer_id))
      expect(page).send to_probably, have_link(dance.user.name, href: user_path(dance.user_id))
      expect(page).send to_probably, have_text(dance.created_at.localtime.strftime("%-m/%-d/%Y"))
    end
  end

  describe 'pagination' do
    def have_turn_page_button(*args)
      have_css(turn_page_button_css(*args))
    end

    def turn_page_button_css(label, disabled=false)
      "button[data-testid=#{label.inspect}]#{disabled ? '[disabled]' : ''}"
    end

    let! (:dances) { 52.times.map {|i| FactoryGirl.create(:dance, title: "dance-#{i}.", created_at: now - i.hours)} }
    before { tag_all_dances }
    it "turning pages" do
      visit(s_path)
      # first page
      10.times {|i| expect(page).to have_link("dance-#{i}.")}
      expect(page).to have_text('Showing 1 to 10 of 52 dances')
      expect(page).to have_turn_page_button('<<', disabled: true)# have_css('button[data-testid="<<"][disabled]')
      expect(page).to have_turn_page_button('<', disabled: true)
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      page.find(turn_page_button_css('>')).click
      # second page
      10.times {|i| expect(page).to have_link("dance-#{i+10}.")}
      expect(page).to have_text('Showing 11 to 20 of 52 dances')
      expect(page).to have_turn_page_button('<<')
      expect(page).to have_turn_page_button('<')
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      page.find(turn_page_button_css('<')).click
      # first page
      10.times {|i| expect(page).to have_link("dance-#{i}.")}
      expect(page).to have_text('Showing 1 to 10 of 52 dances')
      expect(page).to have_turn_page_button('<<', disabled: true)
      expect(page).to have_turn_page_button('<', disabled: true)
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      # third page via numeric input
      find('.page-number-entry').fill_in(with: '3') # third page
      10.times {|i| expect(page).to have_link("dance-#{i+20}.")}
      expect(page).to have_text('Showing 21 to 30 of 52 dances')
      expect(page).to have_turn_page_button('<<')
      expect(page).to have_turn_page_button('<')
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
      page.find(turn_page_button_css('>>')).click
      # last (partial) page
      2.times {|i| expect(page).to have_link("dance-#{i+50}.")}
      expect(page).to have_text('Showing 51 to 52 of 52 dances')
      expect(page).to have_turn_page_button('<<')
      expect(page).to have_turn_page_button('<')
      expect(page).to have_turn_page_button('>', disabled: true)
      expect(page).to have_turn_page_button('>>', disabled: true)
      page.find(turn_page_button_css('<<')).click
      # first page
      10.times {|i| expect(page).to have_link("dance-#{i}.")}
      expect(page).to have_text('Showing 1 to 10 of 52 dances')
      expect(page).to have_turn_page_button('<<', disabled: true)
      expect(page).to have_turn_page_button('<', disabled: true)
      expect(page).to have_turn_page_button('>')
      expect(page).to have_turn_page_button('>>')
    end

    it "page size select menu" do
      visit(s_path)
      expect(page).to have_text("Showing 1 to 10 of 52 dances.")
      select('30')
      expect(page).to have_text("Showing 1 to 30 of 52 dances.")
      page.find(turn_page_button_css('>')).click
      expect(page).to have_text("Showing 31 to 52 of 52 dances.")
      (dances.length-30).times do |i|
        expect(page).to have_link("dance-#{i+30}.")
      end
    end
  end

  describe 'columns' do
    let (:dances) {[:dance, :box_the_gnat_contra, :call_me].map {|d| FactoryGirl.create(d)}}
    it "Clicking vis toggles buttons cause columns to disappear" do
      dances
      tag_all_dances
      visit(s_path)
      %w[Title Choreographer Formation Hook User Entered].each do |col|
        expect(page).to have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-active', text: col)
        expect(page).to_not have_css('button.toggle-vis-inactive', text: col)
        click_button col
        expect(page).to_not have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-inactive', text: col)
        expect(page).to_not have_css('button.toggle-vis-active', text: col)
        click_button col
        expect(page).to have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-active', text: col)
        expect(page).to_not have_css('button.toggle-vis-inactive', text: col)
      end
      %w[Updated Sharing Figures].each do |col|
        expect(page).to_not have_css('.dances-table-react th', text: col)
        expect(page).to_not have_css('button.toggle-vis-active', text: col)
        expect(page).to  have_css('button.toggle-vis-inactive', text: col)
        click_button col
        expect(page).to have_css('.dances-table-react th', text: col)
        expect(page).to_not have_css('button.toggle-vis-inactive', text: col)
        expect(page).to have_css('button.toggle-vis-active', text: col)
        click_button col
        expect(page).to_not have_css('.dances-table-react th', text: col)
        expect(page).to have_css('button.toggle-vis-inactive', text: col)
        expect(page).to_not have_css('button.toggle-vis-active', text: col)
      end
    end

    it 'published column cells' do
      dances
      tag_all_dances
      with_login do |user|
        dances.each_with_index do |dance, i|
          publish = [:off, :sketchbook, :all][i]
          publish_string = ['private', 'sketchbook', 'everywhere'][i]
          dance.update!(publish: publish, user: user)
          visit(s_path)
          click_button 'Sharing'
          expect(page).to have_css('tr', text: /#{dance.title}.*#{publish_string}/)
        end
      end
    end

    describe 'matching figures column' do
      it 'whole dance' do
        dances
        tag_all_dances
        visit(s_path)
        expect(page).to_not have_css(:th, text: "Figures")
        expect(page).to_not have_content('whole dance')
        click_button 'Figures'
        expect(page).to have_css(:th, text: "Figures") # js wait
        expect(page).to have_content('whole dance', count: 3)
      end

      it 'some matches prints figures' do
        # TODO: update how we pass the filter when there's a user-facing way to send figure queries
        # 4NOW: stub the controller, heh heh -dm 01-30-2020
        expect_any_instance_of(Api::V1::DancesController).to receive(:filter).and_return(['figure', 'circle'])
        # mock
        dances
        tag_all_dances
        visit(s_path)
        click_button 'Figures'
        expect(page).to have_css('tr', text: /The Rendevouz.*\n?circle left 4 places\ncircle left 3 places/)
        expect(page).to have_css('tr', text: /Call Me.*\n?circle left 3 places/)
      end
    end
  end

  it "sentence displays how many search results match" do
    dbsize = 12
    dbsize.times.map {|i| FactoryGirl.create(:dance, created_at: now - i.hours)}
    tag_all_dances
    visit(s_path)
    expect(page).to have_content("Showing 1 to 10 of #{dbsize} dances.")
  end

  describe "sorting" do
    it "clicking a header displays that column in descending order" do
      shuffled_ints = [7, 0, 10, 8, 9, 2, 11, 6, 3, 5, 1, 4]
      dances = shuffled_ints.map.with_index {|shuffled_int, i|
        FactoryGirl.create(:dance, title: "dance-#{shuffled_int.to_s.rjust(2, '0')}", created_at: now - i.hours)
      }
      dances_sorted = dances.dup.sort_by(&:title)
      tag_all_dances
      visit(s_path)
      dances.each_with_index do |dance, i|
        expect(page).send(i < 10 ? :to : :to_not, have_text(dance.title))
      end
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      unsorted_dances_titles_regex = Regexp.new(dances.take(10).map(&:title).join('.*\n'))
      expect(page).to have_text(unsorted_dances_titles_regex)

      # first click makes it sort descending
      find('th', text: 'Title').click
      expect(page).to have_css('th .glyphicon-sort-by-attributes')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      dances_sorted.each_with_index do |dance, i|
        expect(page).send(i < 10 ? :to : :to_not, have_text(dance.title))
      end
      # we see we have the dances, but do we have them in order? dance-00, dance-01, ... dance-09
      first_ten_dances_titles_regex = Regexp.new(dances_sorted.take(10).map(&:title).join('.*\n'))
      expect(page).to have_text(first_ten_dances_titles_regex)

      # second click makes it sort ascending
      find('th', text: 'Title').click
      expect(page).to have_css('th .glyphicon-sort-by-attributes-alt')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      dances_sorted.each_with_index do |dance, i|
        expect(page).send(i >= dances.length-10 ? :to : :to_not, have_text(dance.title))
      end
      # we see we have the dances, but do we have them in order? dance-12, dance-11, ... dance-02
      last_ten_dances_titles_regex = Regexp.new(dances_sorted.reverse.take(10).map(&:title).join('.*\n'))
      expect(page).to have_text(last_ten_dances_titles_regex)

      # third click returns to default sort (which is by descending created_at)
      find('th', text: 'Title').click
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      dances.each_with_index do |dance, i|
        expect(page).send(i < 10 ? :to : :to_not, have_text(dance.title))
      end
      expect(page).to have_text(unsorted_dances_titles_regex)
    end

    it "no weird monkey business with client side sorting" do
      titles = ['40 Years of Penguin Pam', "A Crafty Wave", "24th of June"]
      dances = titles.map {|title| FactoryGirl.create(:dance, title: title)}
      titles_sorted = titles.dup.sort
      tag_all_dances
      visit(s_path)
      find('th', text: 'Title').click
      expect(page).to have_text(Regexp.new(titles_sorted.join('.*\n')))
    end

    it "you can't sort by matching figures" do
      dances = [:dance, :box_the_gnat_contra, :call_me].each_with_index.map do |t, i|
        FactoryGirl.create(t, created_at: now - i.hours)
      end
      the_ordered_regexp = Regexp.new(dances.map(&:title).join('(?:.*\n)+'))
      tag_all_dances
      visit(s_path)
      click_button 'Figures'
      expect(page).to have_content(the_ordered_regexp) # order is time-sorted
      find('th', text: 'Figures').click
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes')
      expect(page).to_not have_css('th .glyphicon-sort-by-attributes-alt')
      expect(page).to have_content(the_ordered_regexp) # order is still time-sorted
    end

    it "sorting all columns (except matching figure) does not give error" do
      dances = [:dance, :box_the_gnat_contra, :call_me].each_with_index.map do |t, i|
        FactoryGirl.create(t, created_at: now - i.hours)
      end
      tag_all_dances
      visit(s_path)
      columns = page.find_all(".toggle-vis-active").to_a + page.find_all(".toggle-vis-inactive").to_a
      column_names = columns.map(&:text)
      column_names_not_to_check = ['Figures']
      column_names_checked = column_names - column_names_not_to_check
      column_names_checked.each do |column_name|
        unless has_css?('.toggle-vis-active', text: column_name)
          click_button(column_name)
        end
        th = find('.dance-table-th', text: column_name)
        expect(th).to have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes-alt')
        th.click
        expect(th).to have_css('.glyphicon-sort-by-attributes')
        expect(th).to_not have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes-alt')
        th.click
        expect(th).to have_css('.glyphicon-sort-by-attributes-alt')
        expect(th).to_not have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes')
        th.click
        expect(th).to have_css('.glyphicon-sort')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes')
        expect(th).to_not have_css('.glyphicon-sort-by-attributes-alt')
      end
    end
  end

  describe "ez-filters" do
    describe "choreographer" do
      let(:dances) { [:dance, :box_the_gnat_contra, :call_me].map {|name| FactoryGirl.create(name)} }

      it "works" do
        call_me = dances.last
        dont_call_me = dances[0, dances.length-2]
        visit(s_path)
        find('.ez-choreographer-filter').fill_in(with: call_me.choreographer)
        dont_call_me.each do |dance|
          expect(page).to_not have_content(dance.title)
        end
      end
    end

    describe "verified" do
      let! (:dances) do
        %w(unverified yaverified verified-by-me).map {|s| FactoryGirl.create(:dance, title: s)}
      end
      let (:user) { FactoryGirl.create(:user) }
      let (:verified) { FactoryGirl.create(:tag, :verified) }
      let! (:dut_somebody_else) { FactoryGirl.create(:dut, tag: verified, dance: dances[1]) }
      let! (:dut_by_me) { FactoryGirl.create(:dut, tag: verified, dance: dances[2], user: user) }
      let (:unverified_dance) { dances[0] }
      let (:verified_dance) { dances[1] }
      let (:verified_by_me_dance) { dances[2] }

      it "'verified' and 'not verified' checkboxes work" do
        visit(s_path)
        expect_dances(verified: true, not_verified: false) # the default
        check 'ez-not-verified'
        expect_dances(verified: true, not_verified: true)
        uncheck 'ez-verified', match: :prefer_exact
        expect_dances(verified: false, not_verified: true)
        uncheck 'ez-not-verified'
        expect_dances(verified: false, not_verified: false)
        check 'ez-verified', match: :prefer_exact
        expect_dances(verified: true, not_verified: false)
      end

      it "'verified by me' and 'not verified by me' checkboxes work" do
        with_login(user: user) do
          visit(s_path)
          expect_dances(verified: true) # the default
          uncheck 'ez-verified', match: :prefer_exact
          expect_dances()
          check 'ez-not-verified-by-me'
          expect_dances(not_verified_by_me: true)
          check 'ez-verified-by-me'
          expect_dances(verified_by_me: true, not_verified_by_me: true)
          uncheck 'ez-not-verified-by-me'
          expect_dances(verified_by_me: true)
          uncheck 'ez-verified-by-me'
          expect_dances()
        end
      end

      def expect_dances(verified: false,
                        not_verified: false,
                        verified_by_me: false,
                        not_verified_by_me: false)
        expect(page).send(not_verified || not_verified_by_me ? :to : :to_not, have_content(unverified_dance.title))
        expect(page).send(verified || not_verified_by_me ? :to : :to_not, have_content(verified_dance.title))
        expect(page).send(verified || verified_by_me ? :to : :to_not, have_content(verified_by_me_dance.title))
      end

      it "verified by me and not verified by me are disabled when not logged in"
    end
  end

  def tag_all_dances(tag: FactoryGirl.create(:tag, :verified), user: FactoryGirl.create(:user))
    Dance.all.each do |dance|
      FactoryGirl.create(:dut, dance: dance, tag: tag, user: user)
    end
  end
end
{'fraction_non_alphanumeric': 0.13765043337282534, 'fraction_numerical': 0.0094780819355241, 'mean_word_length': 3.123280627329991, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5508910', 'n_tokens_mistral': 11284, 'n_tokens_neox': 10824, 'n_words': 2267}