diff options
| author | Miquel Sabaté Solà <msabate@suse.com> | 2024-03-13 18:03:43 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <msabate@suse.com> | 2024-03-13 18:03:43 +0100 |
| commit | a7791635aa98f012d35f97c3c5288494bbb28e38 (patch) | |
| tree | bad987e6b4d10ad2f7cd02e40658d464907595ee /test | |
| download | operum-a7791635aa98f012d35f97c3c5288494bbb28e38.tar.gz operum-a7791635aa98f012d35f97c3c5288494bbb28e38.zip | |
Initial commit
Signed-off-by: Miquel Sabaté Solà <msabate@suse.com>
Diffstat (limited to 'test')
| -rw-r--r-- | test/application_system_test_case.rb | 26 | ||||
| -rw-r--r-- | test/controllers/exports_controller_test.rb | 24 | ||||
| -rw-r--r-- | test/fixtures/action_text/rich_texts.yml | 4 | ||||
| -rw-r--r-- | test/fixtures/comments.yml | 2 | ||||
| -rw-r--r-- | test/fixtures/files/all.uoc.tex | 9 | ||||
| -rw-r--r-- | test/fixtures/searches.yml | 4 | ||||
| -rw-r--r-- | test/fixtures/tag_references.yml | 15 | ||||
| -rw-r--r-- | test/fixtures/tags.yml | 5 | ||||
| -rw-r--r-- | test/fixtures/things.yml | 39 | ||||
| -rw-r--r-- | test/fixtures/users.yml | 4 | ||||
| -rw-r--r-- | test/models/comment_test.rb | 18 | ||||
| -rw-r--r-- | test/models/search_test.rb | 90 | ||||
| -rw-r--r-- | test/models/tag_test.rb | 16 | ||||
| -rw-r--r-- | test/models/thing_test.rb | 95 | ||||
| -rw-r--r-- | test/models/user_test.rb | 28 | ||||
| -rw-r--r-- | test/system/comments_test.rb | 103 | ||||
| -rw-r--r-- | test/system/exports_test.rb | 27 | ||||
| -rw-r--r-- | test/system/licenses_test.rb | 11 | ||||
| -rw-r--r-- | test/system/searches_test.rb | 123 | ||||
| -rw-r--r-- | test/system/sessions_test.rb | 27 | ||||
| -rw-r--r-- | test/system/shared_searches_test.rb | 34 | ||||
| -rw-r--r-- | test/system/tags_test.rb | 40 | ||||
| -rw-r--r-- | test/system/things_test.rb | 102 | ||||
| -rw-r--r-- | test/test_helper.rb | 18 |
24 files changed, 864 insertions, 0 deletions
diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb new file mode 100644 index 0000000..eaa28b0 --- /dev/null +++ b/test/application_system_test_case.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'test_helper' + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400] + + # Sign in with the default user. + def sign_in! + visit new_sessions_url + + fill_in I18n.t('activerecord.attributes.user.username'), with: users(:user).username + fill_in I18n.t('activerecord.attributes.user.password'), with: '12341234' + click_on I18n.t('sessions.sign-in') + + assert_text I18n.t('searches.home') + end + + # Sign out the current user if it's already signed in, otherwise do nothing. + def sign_out_maybe! + click_on I18n.t('sessions.sign-out') + assert_text I18n.t('sessions.title') + rescue Capybara::ElementNotFound + # We were not logged in, do nothing. + end +end diff --git a/test/controllers/exports_controller_test.rb b/test/controllers/exports_controller_test.rb new file mode 100644 index 0000000..42ed1a2 --- /dev/null +++ b/test/controllers/exports_controller_test.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class ExportsControllerTest < ActionDispatch::IntegrationTest + # We need the session to be initialized as a signed in user. + setup { post sessions_url, params: { username: users(:user).username, password: '12341234' } } + + test 'csv: works' do + get search_exports_url(0, format: 'csv') + + body = @response.body.split("\n") + assert body.size == 2 + assert body.first.split(',')[0] == things(:thing2).target + assert body.last.split(',')[0] == things(:thing1).target + + assert @response.media_type == 'text/csv' + end + + test 'uoc: works' do + get search_exports_url(0, format: 'uoc') + + assert @response.body == file_fixture('all.uoc.tex').read + assert @response.media_type == 'application/x-tex' + end +end diff --git a/test/fixtures/action_text/rich_texts.yml b/test/fixtures/action_text/rich_texts.yml new file mode 100644 index 0000000..8c95217 --- /dev/null +++ b/test/fixtures/action_text/rich_texts.yml @@ -0,0 +1,4 @@ +comment1: + record: comment1 (Comment) + name: content + body: <p>Such awesome content from Miquel</p> diff --git a/test/fixtures/comments.yml b/test/fixtures/comments.yml new file mode 100644 index 0000000..f61437d --- /dev/null +++ b/test/fixtures/comments.yml @@ -0,0 +1,2 @@ +comment1: + thing_id: <%= ActiveRecord::FixtureSet.identify(:thing1) %> diff --git a/test/fixtures/files/all.uoc.tex b/test/fixtures/files/all.uoc.tex new file mode 100644 index 0000000..227a2bb --- /dev/null +++ b/test/fixtures/files/all.uoc.tex @@ -0,0 +1,9 @@ +\chapter{Bibliografia} + +{\setlength{\parskip}{-0.3cm} + +\hypertarget{target2}{\textsc{Sabaté}, Miquel; \textsc{Nom} (eds.) (2024). \emph{This is a 2}. Dins de \emph{Some other thing}, 22-24. This is a note 2. Publisher 2, Address 2: 2024.} + +\\~\\\hypertarget{target1}{\textsc{Sabaté}, Miquel; \textsc{Smith}, John; \textsc{cognom2}, Nom cognom1; \textsc{cognom3 cognom4}, Nom (2024). \emph{This is a title 1}. Dins de \emph{Some other thing}, 22-24. This is a note 1. Publisher 1. [\url{http://example.com}]. [Última data de consulta: 24 de febrer de 2024].} + +} diff --git a/test/fixtures/searches.yml b/test/fixtures/searches.yml new file mode 100644 index 0000000..ffc7a28 --- /dev/null +++ b/test/fixtures/searches.yml @@ -0,0 +1,4 @@ +search1: + name: 'search1' + body: "tag:\"tag1\"" + user_id: <%= ActiveRecord::FixtureSet.identify(:user) %> diff --git a/test/fixtures/tag_references.yml b/test/fixtures/tag_references.yml new file mode 100644 index 0000000..d6267d5 --- /dev/null +++ b/test/fixtures/tag_references.yml @@ -0,0 +1,15 @@ +thing1tag1: + tag_id: <%= ActiveRecord::FixtureSet.identify(:tag1) %> + taggable: thing1 (Thing) + +thing1tag2: + tag_id: <%= ActiveRecord::FixtureSet.identify(:tag2) %> + taggable: thing1 (Thing) + +thing2tag1: + tag_id: <%= ActiveRecord::FixtureSet.identify(:tag1) %> + taggable: thing2 (Thing) + +comment1tag1: + tag_id: <%= ActiveRecord::FixtureSet.identify(:tag1) %> + taggable: comment1 (Comment) diff --git a/test/fixtures/tags.yml b/test/fixtures/tags.yml new file mode 100644 index 0000000..1e0ce52 --- /dev/null +++ b/test/fixtures/tags.yml @@ -0,0 +1,5 @@ +tag1: + name: 'tag1' + +tag2: + name: 'tag2' diff --git a/test/fixtures/things.yml b/test/fixtures/things.yml new file mode 100644 index 0000000..069cf85 --- /dev/null +++ b/test/fixtures/things.yml @@ -0,0 +1,39 @@ +thing1: + target: 'target1' + title: 'This is a title 1' + publisher: 'Publisher 1' + authors: 'Miquel Sabaté, John Smith, Nom cognom1 cognom2, Nom _cognom3 cognom4_' + editors: false + address: + year: 2024 + url: 'http://example.com' + location: 'Somewhere' + insideof: 'Some other thing' + pages: '22-24' + note: 'This is a note 1' + rate: 5 + status: <%= Thing.statuses[:read] %> + kind: <%= Thing.kinds[:novel] %> + access: 2024-02-24 17:24:12 + bought_at: 2024-02-24 17:24:12 + user_id: <%= ActiveRecord::FixtureSet.identify(:user) %> + +thing2: + target: 'target2' + title: 'This is a 2' + publisher: 'Publisher 2' + authors: 'Miquel Sabaté, Nom' + editors: true + address: 'Address 2' + year: 2024 + url: 'http://example.com' + location: 'Somewhere' + insideof: 'Some other thing' + pages: '22-24' + note: 'This is a note 2' + rate: 8 + status: <%= Thing.statuses[:read] %> + kind: <%= Thing.kinds[:poetry] %> + access: 2024-02-24 17:24:12 + bought_at: 2024-02-24 17:24:12 + user_id: <%= ActiveRecord::FixtureSet.identify(:user) %> diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..66baf92 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,4 @@ +user: + username: user + password_digest: <%= BCrypt::Password.create("12341234", cost: 4) %> + last_search_id: null diff --git a/test/models/comment_test.rb b/test/models/comment_test.rb new file mode 100644 index 0000000..087963a --- /dev/null +++ b/test/models/comment_test.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'test_helper' + +class CommentTest < ActiveSupport::TestCase + test 'content is present' do + comment = Comment.new(thing_id: things(:thing1).id) + assert_raise(ActiveRecord::RecordInvalid) { comment.save! } + + comment.content = 'whatever' + assert_difference('Comment.count') { comment.save! } + end + + test 'has many tags through tag_references' do + comment = comments(:comment1) + assert comment.tags.size == 1 + end +end diff --git a/test/models/search_test.rb b/test/models/search_test.rb new file mode 100644 index 0000000..9614bc0 --- /dev/null +++ b/test/models/search_test.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require 'test_helper' + +class SearchTest < ActiveSupport::TestCase + test 'name and body have to be present and unique' do + search = Search.new(user_id: users(:user).id) + assert_raise(ActiveRecord::RecordInvalid) { search.save! } + + search.name = 'new search' + assert_raise(ActiveRecord::RecordInvalid) { search.save! } + + search.name = nil + search.body = 'body' + assert_raise(ActiveRecord::RecordInvalid) { search.save! } + + search.name = searches(:search1).name + assert_raise(ActiveRecord::RecordInvalid) { search.save! } + + search.name = 'another' + search.body = searches(:search1).body + assert_raise(ActiveRecord::RecordInvalid) { search.save! } + + search.body = 'another body' + assert_difference('Search.count') { search.save! } + end + + ## + # Results. + + test 'returns all things when an empty body is given' do + res = Search.new.results + + assert res[:things].size == 2 + assert res[:things][0][:target] == things(:thing2).target + assert res[:things][1][:target] == things(:thing1).target + end + + test 'returns everything matching a specific tag' do + res = Search.new(body: "tag:'#{tags(:tag1).name}'").results + + assert res[:things].size == 2 + assert res[:things][0][:target] == things(:thing2).target + assert res[:things][1][:target] == things(:thing1).target + assert res[:comments].size == 1 + assert res[:comments][0][:id] == comments(:comment1).id + end + + test 'returns everything matching two tags' do + res = Search.new(body: "tag:'#{tags(:tag1).name}' tag:'#{tags(:tag2).name}'").results + + assert res[:things].size == 1 + assert res[:things][0][:target] == things(:thing1).target + assert res[:comments].empty? + end + + test 'returns everything matching a given text' do + res = Search.new(body: 'Miquel').results + + assert res[:things].size == 2 + assert res[:things][0][:target] == things(:thing2).target + assert res[:things][1][:target] == things(:thing1).target + assert res[:comments].size == 1 + assert res[:comments][0][:id] == comments(:comment1).id + end + + test 'returns everything matching two tags and a given text' do + res = Search.new(body: "Miquel tag:'#{tags(:tag1).name}' tag:'#{tags(:tag2).name}'").results + + assert res[:things].size == 1 + assert res[:things][0][:target] == things(:thing1).target + assert res[:comments].empty? + end + + test 'returns everything matching a given compound text' do + res = Search.new(body: 'some other').results + + assert res[:things].size == 2 + assert res[:things][0][:target] == things(:thing2).target + assert res[:things][1][:target] == things(:thing1).target + assert res[:comments].empty? + end + + test 'returns an empty result with unknown fields' do + res = Search.new(body: 'whatever:"unknown"').results + + assert res[:things].empty? + assert res[:comments].empty? + end +end diff --git a/test/models/tag_test.rb b/test/models/tag_test.rb new file mode 100644 index 0000000..dafb8e4 --- /dev/null +++ b/test/models/tag_test.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'test_helper' + +class TagTest < ActiveSupport::TestCase + test 'name is present and unique' do + tag = Tag.new + assert_raise(ActiveRecord::RecordInvalid) { tag.save! } + + tag = Tag.new(name: tags(:tag1).name) + assert_raise(ActiveRecord::RecordInvalid) { tag.save! } + + tag.name = 'another' + assert_difference('Tag.count') { tag.save! } + end +end diff --git a/test/models/thing_test.rb b/test/models/thing_test.rb new file mode 100644 index 0000000..0b3961e --- /dev/null +++ b/test/models/thing_test.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require 'test_helper' + +class ThingTest < ActiveSupport::TestCase + test 'validates presence' do + assert_raise(ActiveRecord::RecordInvalid) { Thing.new.save! } + + # Missing 'title' + assert_raise(ActiveRecord::RecordInvalid) do + Thing.new(target: 'target', authors: 'Author', + user_id: users(:user).id, rate: 5, + status: Thing.statuses[:read], kind: Thing.kinds[:novel]).save! + end + + # Missing 'target' + assert_raise(ActiveRecord::RecordInvalid) do + Thing.new(title: 'title', authors: 'Author', + user_id: users(:user).id, rate: 5, + status: Thing.statuses[:read], kind: Thing.kinds[:novel]).save! + end + + # Missing 'authors' + assert_raise(ActiveRecord::RecordInvalid) do + Thing.new(title: 'title', target: 'target', + user_id: users(:user).id, rate: 5, + status: Thing.statuses[:read], kind: Thing.kinds[:novel]).save! + end + + # Valid! + assert_difference('Thing.count') do + Thing.new(title: 'title', target: 'target', authors: 'Author', + user_id: users(:user).id, rate: 5, + status: Thing.statuses[:read], kind: Thing.kinds[:novel]).save! + end + end + + test "'rate' has to be between 0 and 10" do + thing = things(:thing1) + + thing.rate = -1 + assert_raise(ActiveRecord::RecordInvalid) { thing.save! } + + thing.rate = 11 + assert_raise(ActiveRecord::RecordInvalid) { thing.save! } + + thing.rate = 5 + thing.save! + end + + test "'status' has to have a value as defined by its enum" do + thing = things(:thing1) + + thing.status = 'whatever' + assert_raise(ActiveRecord::RecordInvalid) { thing.save! } + + thing.status = Thing.statuses[:tobepublished] + thing.save! + end + + test "'kind' has to have a value as defined by its enum" do + thing = things(:thing1) + + thing.kind = 'whatever' + assert_raise(ActiveRecord::RecordInvalid) { thing.save! } + + thing.kind = Thing.kinds[:other] + thing.save! + end + + test 'title and target must be unique' do + thing = things(:thing1).dup + + thing.title = 'another' + assert_raise(ActiveRecord::RecordInvalid) { thing.save! } + + thing.target = 'also another' + thing.title = things(:thing1).title + assert_raise(ActiveRecord::RecordInvalid) { thing.save! } + + thing.target = 'also another' + thing.title = 'now for real' + assert_difference('Thing.count') { thing.save! } + end + + test 'has many comments' do + thing = things(:thing1) + assert thing.comments.size == 1 + end + + test 'has many tags through tag_references' do + thing = things(:thing1) + assert thing.tags.size == 2 + end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..6ff5e19 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + test 'has to provide username and password' do + user = User.new + assert_raise(ActiveRecord::RecordInvalid) { user.save! } + + user.username = 'whatever' + assert_raise(ActiveRecord::RecordInvalid) { user.save! } + + user.password = '1234' + user.password_confirmation = '12345' + assert_raise(ActiveRecord::RecordInvalid) { user.save! } + + user.password_confirmation = '1234' + assert_difference('User.count') do + user.save! + end + end + + test 'username has to be unique' do + user = User.new(username: users(:user).username, + password: '1234', password_confirmation: '1234') + assert_raise(ActiveRecord::RecordInvalid) { user.save! } + end +end diff --git a/test/system/comments_test.rb b/test/system/comments_test.rb new file mode 100644 index 0000000..b2490b4 --- /dev/null +++ b/test/system/comments_test.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class CommentsTest < ApplicationSystemTestCase + setup { sign_in! } + + ## + # In things#show + + test 'things#show: the hidden form is shown when clicking the proper button' do + visit thing_url(things(:thing1)) + + click_on I18n.t('comments.new') + assert_text I18n.t('tags.new-action'), count: 1 + + click_on I18n.t('general.cancel') + assert_text I18n.t('tags.new-action'), count: 0 + end + + test 'things#show: you can add a new comment' do + visit thing_url(things(:thing1)) + + click_on I18n.t('comments.new') + find(:css, '#comment_content').set('a new comment') + find("#comment_tag_ids_#{tags(:tag1).id}").click + find("#comment_tag_ids_#{tags(:tag2).id}").click + + click_on I18n.t('helpers.submit.create') + + assert_text "#{I18n.t('comments.title')} #2" + assert_text 'a new comment' + assert_text "#{I18n.t('tags.title')}: #{tags(:tag1).name}, #{tags(:tag2).name}" + assert page.current_path == thing_path(things(:thing1)) + end + + test 'things#show: you can update a comment' do + visit thing_url(things(:thing1)) + + click_on I18n.t('general.edit').capitalize + find(:css, '#comment_content').set('updated comment') + + find("#comment_#{comments(:comment1).id} input[type=submit]").click + assert_text 'updated comment' + assert page.current_path == thing_path(things(:thing1)) + end + + test 'things#show: you can delete a comment' do + visit thing_url(things(:thing1)) + + all('.delete-comment').last.click + assert_text I18n.t('comments.none') + assert page.current_path == thing_path(things(:thing1)) + end + + ## + # In things#edit + + test 'things#edit: the hidden form is shown when clicking the proper button' do + visit edit_thing_url(things(:thing1)) + + click_on I18n.t('comments.new') + assert_text I18n.t('tags.new-action'), count: 2 + + click_on I18n.t('general.cancel') + assert_text I18n.t('tags.new-action'), count: 1 + end + + test 'things#edit: you can add a new comment' do + visit edit_thing_url(things(:thing1)) + + click_on I18n.t('comments.new') + find(:css, '#comment_content').set('a new comment') + find("#comment_tag_ids_#{tags(:tag1).id}").click + find("#comment_tag_ids_#{tags(:tag2).id}").click + + click_on I18n.t('helpers.submit.create') + + assert_text "#{I18n.t('comments.title')} #2" + assert_text 'a new comment' + assert_text "#{I18n.t('tags.title')}: #{tags(:tag1).name}, #{tags(:tag2).name}" + assert page.current_path == edit_thing_path(things(:thing1)) + end + + test 'things#edit: you can update a comment' do + visit edit_thing_url(things(:thing1)) + + click_on I18n.t('general.edit').capitalize + find(:css, '#comment_content').set('updated comment') + + find("#comment_#{comments(:comment1).id} input[type=submit]").click + assert_text 'updated comment' + assert page.current_path == edit_thing_path(things(:thing1)) + end + + test 'things#edit: you can delete a comment' do + visit edit_thing_url(things(:thing1)) + + all('.delete-comment').last.click + assert_text I18n.t('comments.none') + assert page.current_path == edit_thing_path(things(:thing1)) + end +end diff --git a/test/system/exports_test.rb b/test/system/exports_test.rb new file mode 100644 index 0000000..b324321 --- /dev/null +++ b/test/system/exports_test.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class ExportsTest < ApplicationSystemTestCase + setup do + sign_in! + end + + test 'can access exports from the hidden menu' do + find('#toggle-hidden-global-menu').click + assert_text I18n.t('searches.export.action') + + click_on I18n.t('searches.export.action') + assert_text I18n.t('searches.export.note-msg') + assert page.current_path == new_search_exports_path(0) + end + + test 'can export using multiple formats' do + visit new_search_exports_path(0) + + assert find('#export-format-button')[:href].ends_with?('/searches/0/exports.csv') + + find('#export-select-format').select('UOC') + assert find('#export-format-button')[:href].ends_with?('/searches/0/exports.uoc') + end +end diff --git a/test/system/licenses_test.rb b/test/system/licenses_test.rb new file mode 100644 index 0000000..1e26664 --- /dev/null +++ b/test/system/licenses_test.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class LicensesTest < ApplicationSystemTestCase + test 'can reach #show without login' do + visit license_url + + assert_text 'AGPLv3' + end +end diff --git a/test/system/searches_test.rb b/test/system/searches_test.rb new file mode 100644 index 0000000..a400e71 --- /dev/null +++ b/test/system/searches_test.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class SearchesTest < ApplicationSystemTestCase + setup do + # All actions will require the user to be logged in. + sign_in! + end + + test 'root url is searches#index, which contains all things plus the tabs we expect' do + visit root_url + + # All searches are listed. + assert_text I18n.t('searches.home') + searches.each { |s| assert_text s.name } + + # All things are listed + things.each { |t| assert_text t.title } + end + + test 'the hidden menu should allow us to go into the searches#new url' do + find('#toggle-hidden-global-menu').click + assert_text I18n.t('searches.title') + + click_on I18n.t('searches.object') + assert find('#search_body') + assert page.current_path == new_search_path + end + + test 'can perform a new search' do + visit new_search_url + + # Fill in the body input and press enter, otherwise the javascript + # controller won't fire up. + fill_in 'search_body', with: 'Miquel' + find('#search_body').native.send_keys(:return) + + # It's actually a pretty generous search: it should give us all thing and a + # comment. + assert_text I18n.t('searches.save') + assert_text things(:thing1).title + assert_text things(:thing2).title + assert_text I18n.t('comments.title') + assert_text tags(:tag1).name + end + + test 'can save a new search' do + visit new_search_url + + # Fill in the body input and press enter, otherwise the javascript + # controller won't fire up. + fill_in 'search_body', with: 'Autor' + find('#search_body').native.send_keys(:return) + + # Hit the save button so the hidden form appears. + assert_text I18n.t('searches.save') + find('#save-search').click + assert_text I18n.t('searches.public') + + fill_in 'Name', with: 'Nova cerca' + click_on I18n.t('helpers.submit.create') + + assert_text 'Nova cerca' + assert page.current_path == search_path(Search.find_by(name: 'Nova cerca')) + end + + test 'can edit a search that is not the Home' do + # Home cannot be edited. + find('#toggle-hidden-global-menu').click + assert_selector 'a', text: I18n.t('general.edit'), count: 0 + + # Select search1 + click_on searches(:search1).name + assert_selector 'a', text: things(:thing1).title, count: 2 + find('#toggle-hidden-global-menu').click + + # It can be edited! + assert_text I18n.t('general.edit') + click_on I18n.t('general.edit') + + # If you click on it, you will be on the edit page for it. + assert find('#search_body') + assert page.current_path == edit_search_path(searches(:search1)) + end + + test 'edit an existing search works' do + visit edit_search_url(searches(:search1)) + + find('#search_body').native.send_keys(:return) + + # Hit the save button so the hidden form appears. + assert_text I18n.t('searches.save') + find('#save-search').click + assert_text I18n.t('searches.public') + + # Update the name. + fill_in 'Name', with: 'Nova cerca' + click_on I18n.t('helpers.submit.update') + + # We have been redirected to search#show, and the name has been refreshed. + assert_selector 'a', text: searches(:search1).name, count: 0 + assert_text 'Nova cerca' + assert page.current_path == search_path(searches(:search1)) + end + + test 'can delete a search that is not the Home' do + # Home cannot be deleted. + find('#toggle-hidden-global-menu').click + assert_selector 'a', text: I18n.t('general.delete'), count: 0 + + # Select search1 + click_on searches(:search1).name + assert_selector 'a', text: things(:thing1).title, count: 2 + find('#toggle-hidden-global-menu').click + + # It can be deleted! + assert_text I18n.t('general.delete') + accept_alert { click_on I18n.t('general.delete') } + assert_selector 'a', text: searches(:search1).name, count: 0 + assert Search.none? + end +end diff --git a/test/system/sessions_test.rb b/test/system/sessions_test.rb new file mode 100644 index 0000000..2d01eef --- /dev/null +++ b/test/system/sessions_test.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class SessionsTest < ApplicationSystemTestCase + test 'logs in successfully' do + sign_in! + end + + test 'fails to log in with wrong password' do + visit new_sessions_url + + fill_in I18n.t('activerecord.attributes.user.username'), with: users(:user).username + fill_in I18n.t('activerecord.attributes.user.password'), with: 'I AM ERROR' + click_on I18n.t('sessions.sign-in') + + assert_text I18n.t('sessions.wrong-credentials') + end + + test 'logs out successfully' do + sign_in! + + click_on I18n.t('sessions.sign-out') + + assert_text I18n.t('sessions.title') + end +end diff --git a/test/system/shared_searches_test.rb b/test/system/shared_searches_test.rb new file mode 100644 index 0000000..0cfc4bd --- /dev/null +++ b/test/system/shared_searches_test.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class SharedSearchesTest < ApplicationSystemTestCase + test 'can access shared_searches#index from the hidden menu' do + sign_in! + + find('#toggle-hidden-global-menu').click + assert_text I18n.t('searches.shared.title').downcase + + click_on I18n.t('searches.shared.title').downcase + assert_text I18n.t('searches.shared.none') + end + + test 'cannot access shared_searches#index if not logged in' do + sign_out_maybe! + + visit shared_searches_path + assert_text I18n.t('sessions.title') + assert page.current_path == new_sessions_path + end + + test 'shared_searches#show gives us the expected results' do + # NOTE: not logged in! + + searches(:search1).update!(shared: true) + + visit search_shared_path(searches(:search1)) + assert_text things(:thing1).title + assert_text things(:thing2).title + assert_text I18n.t('comments.title') + end +end diff --git a/test/system/tags_test.rb b/test/system/tags_test.rb new file mode 100644 index 0000000..1ee83a9 --- /dev/null +++ b/test/system/tags_test.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class SharedSearchesTest < ApplicationSystemTestCase + setup { sign_in! } + + test 'lists all the tags' do + visit tags_url + + tags.each { |t| assert_text t.name } + end + + test 'can create a new tag' do + visit new_tag_url + + fill_in I18n.t('activerecord.attributes.tag.name'), with: 'whatever' + assert_difference 'Tag.count' do + click_on I18n.t('helpers.submit.create') + assert_text 'whatever' + end + end + + test 'gives feedback on errors' do + visit new_tag_url + + fill_in I18n.t('activerecord.attributes.tag.name'), with: tags(:tag1).name + click_on I18n.t('helpers.submit.create') + assert_text "#{I18n.t('activerecord.attributes.tag.name')} #{I18n.t('errors.messages.taken')}" + end + + test 'can delete an existing tag' do + visit tags_url + + assert_difference 'Tag.count', -1 do + click_link(I18n.t('general.delete'), match: :first) + assert_text I18n.t('tags.title') + end + end +end diff --git a/test/system/things_test.rb b/test/system/things_test.rb new file mode 100644 index 0000000..9dd482d --- /dev/null +++ b/test/system/things_test.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require 'application_system_test_case' + +class ThingsTest < ApplicationSystemTestCase + setup { sign_in! } + + test 'the hidden menu has a things#new link' do + find('#toggle-hidden-global-menu').click + assert_text I18n.t('things.object').downcase + + click_on I18n.t('things.object').downcase + assert_text I18n.t('activerecord.attributes.thing.title') + + assert page.current_path == new_thing_path + end + + test 'you can click on a thing listed on the search to go to the its #show page' do + click_on things(:thing1).title + + assert_text I18n.t('activerecord.attributes.thing.title') + + assert page.current_path == edit_thing_path(things(:thing1)) + end + + test 'you can create a new thing' do + visit new_thing_url + + fill_in I18n.t('activerecord.attributes.thing.title'), with: 'new title' + fill_in I18n.t('activerecord.attributes.thing.authors'), with: 'author' + fill_in I18n.t('activerecord.attributes.thing.target'), with: 'identifier' + fill_in I18n.t('activerecord.attributes.thing.rate'), with: 5 + find("#thing_tag_ids_#{tags(:tag1).id}").click + + click_on I18n.t('helpers.submit.create') + + assert_text I18n.t('things.create-success') + + # Ensure that tag references are properly created. + tags = Thing.find_by(title: 'new title').tags + assert tags.size == 1 + assert tags.first.name == tags(:tag1).name + + # You can go back to create another thing with a convenient link. + click_on I18n.t('things.create-another') + assert_text I18n.t('activerecord.attributes.thing.title') + assert page.current_path == new_thing_path + end + + test 'you get feedback from wrong values for a new thing' do + visit new_thing_url + + fill_in I18n.t('activerecord.attributes.thing.title'), with: things(:thing1).title + fill_in I18n.t('activerecord.attributes.thing.authors'), with: 'author' + fill_in I18n.t('activerecord.attributes.thing.target'), with: 'identifier' + fill_in I18n.t('activerecord.attributes.thing.rate'), with: 5 + find("#thing_tag_ids_#{tags(:tag1).id}").click + + click_on I18n.t('helpers.submit.create') + + assert_text "#{I18n.t('activerecord.attributes.thing.title')} " \ + "#{I18n.t('errors.messages.taken')}" + end + + test 'you can update a value from a thing' do + visit edit_thing_url(things(:thing1)) + + # Originally :thing1 has references to :tag1 and :tag2. This test will + # remove the reference to :tag1. + assert things(:thing1).tag_references.size == 2 + + fill_in I18n.t('activerecord.attributes.thing.title'), with: 'another thing entirely' + find("#thing_tag_ids_#{tags(:tag1).id}").click + click_on I18n.t('helpers.submit.update') + + assert_text I18n.t('things.update-success') + + # Tag references updated: only one reference (:tag2). + tags = things(:thing1).reload.tags + assert tags.size == 1 + assert tags.first.id = tags(:tag2).id + end + + test 'you get feedback from wrong values for a thing' do + visit edit_thing_url(things(:thing1)) + + fill_in I18n.t('activerecord.attributes.thing.title'), with: things(:thing2).title + click_on I18n.t('helpers.submit.update') + + assert_text "#{I18n.t('activerecord.attributes.thing.title')} " \ + "#{I18n.t('errors.messages.taken')}" + end + + test 'you can delete a thing' do + visit edit_thing_url(things(:thing1)) + + assert_difference 'Thing.count', -1 do + accept_alert { click_on I18n.t('general.delete').capitalize, match: :first } + assert_text I18n.t('things.destroy-success') + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..b13faef --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +ENV['RAILS_ENV'] ||= 'test' +require_relative '../config/environment' +require 'rails/test_help' + +# It helps when writing tests. +require 'ap' + +module ActiveSupport + class TestCase + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + end +end |
