{"action":"created","comment":{"url":"https://api.github.com/repos/otwcode/otwarchive/pulls/comments/93708052","pull_request_review_id":14242199,"id":93708052,"diff_hunk":"@@ -2,11 +2,188 @@\n \n describe WorksController do\n   include LoginMacros\n-  \n+\n+  def it_redirects_to_user_login\n+    expect(response).to have_http_status(:redirect)\n+    expect(response).to redirect_to new_user_session_path\n+  end\n+\n+  describe \"before_filter #clean_work_search_params\" do\n+    let(:params) { nil }\n+\n+    def call_with_params(params)\n+      controller.params = { work_search: params }\n+      controller.clean_work_search_params\n+    end\n+\n+    context \"when no work search parameters are given\" do\n+      it \"redirects to the login screen when no user is logged in\" do\n+        get :clean_work_search_params, params\n+        it_redirects_to_user_login\n+      end\n+\n+      it \"returns a nil\" do\n+        fake_login\n+        controller.params = params\n+        controller.clean_work_search_params\n+        expect(controller.params[:work_search]).to be_nil\n+      end\n+    end\n+\n+    context \"when search parameters are empty\" do\n+      let(:params) { [] }\n+\n+      it \"returns a RecordNotFound exception\" do\n+        call_with_params params\n+        expect(controller.params[:work_search]).to be_empty\n+      end\n+    end\n+\n+    context \"when the query contains countable search parameters\" do\n+      it \"should escape less and greater than in query\" do\n+        [\n+          { params: \"< 5 words\", expected: \"&lt; 5 words\", message: \"Should escape <\" },\n+          { params: \"> 5 words\", expected: \"&gt; 5 words\", message: \"Should escape >\" },\n+        ].each do |settings|\n+          call_with_params({ query: settings[:params] })\n+          expect(controller.params[:work_search][:query])\n+            .to eq(settings[:expected]), settings[:message]\n+        end\n+      end\n+\n+      it \"should convert 'word' to 'word_count'\" do\n+        call_with_params({ query: \"word:6\" })\n+        expect(controller.params[:work_search][:word_count]).to eq(\"6\")\n+      end\n+\n+      it \"should convert 'words' to 'word_count'\" do\n+        call_with_params({ query: \"words:7\" })\n+        expect(controller.params[:work_search][:word_count]).to eq(\"7\")\n+      end\n+\n+      it \"should convert 'hits' queries to 'hits'\" do\n+        call_with_params({ query: \"hits:8\" })\n+        expect(controller.params[:work_search][:hits]).to eq(\"8\")\n+      end\n+\n+      it \"should convert other queries to (pluralized term)_count\" do\n+        %w(kudo comment bookmark).each do |term|\n+          call_with_params({ query: \"#{term}:9\" })\n+          expect(controller.params[:work_search][\"#{term.pluralize}_count\"])\n+            .to eq(\"9\"), \"Search term '#{term}' should become #{term.pluralize}_count key\"\n+        end\n+      end\n+    end\n+\n+    context \"when sort parameters are provided\" do\n+      it \"should convert variations on 'sorted by: X' into :sort_column key\" do\n+        [\n+          \"sort by: words\",\n+          \"sorted by: words\",\n+          \"sorted: words\",\n+          \"sort: words\",\n+          \"sort by < words\",\n+          \"sort by > words\",\n+          \"sort by = words\"\n+        ].each do |query|\n+          call_with_params({ query: query })\n+          expect(controller.params[:work_search][:sort_column])\n+            .to eq(\"word_count\"), \"Sort command '#{query}' should be converted to :sort_column\"\n+        end\n+      end\n+\n+      it \"should convert variations on sort columns to column name\" do\n+        [\n+          { query: \"sort by: word count\", expected: \"word_count\"},\n+          { query: \"sort by: words\", expected: \"word_count\"},\n+          { query: \"sort by: word\", expected: \"word_count\"},\n+          { query: \"sort by: author\", expected: \"authors_to_sort_on\"},\n+          { query: \"sort by: title\", expected: \"title_to_sort_on\"},\n+          { query: \"sort by: date\", expected: \"created_at\"},\n+          { query: \"sort by: date posted\", expected: \"created_at\"},\n+          { query: \"sort by: hits\", expected: \"hits\"},\n+          { query: \"sort by: kudos\", expected: \"kudos_count\"},\n+          { query: \"sort by: comments\", expected: \"comments_count\"},\n+          { query: \"sort by: bookmarks\", expected: \"bookmarks_count\"},\n+        ].each do |settings|\n+          call_with_params({ query: settings[:query] })\n+          actual = controller.params[:work_search][:sort_column]\n+          expect(actual)\n+            .to eq(settings[:expected]),\n+                \"Query '#{settings[:query]}' should be converted to :sort_column '#{settings[:expected]}' but is '#{actual}'\"\n+        end\n+      end\n+\n+      it \"should convert 'ascending' or '>' into :sort_direction key 'asc'\" do\n+        [\n+          \"sort > word_count\",\n+          \"sort: word_count ascending\",\n+          \"sort: hits ascending\",\n+        ].each do |query|\n+          call_with_params({ query: query })","path":"spec/controllers/works_controller_spec.rb","position":123,"original_position":123,"commit_id":"0d6fbea5f5dbf253b8362c30fc5a4b80d844becf","original_commit_id":"0d6fbea5f5dbf253b8362c30fc5a4b80d844becf","user":{"login":"houndci-bot","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci-bot","html_url":"https://github.com/houndci-bot","followers_url":"https://api.github.com/users/houndci-bot/followers","following_url":"https://api.github.com/users/houndci-bot/following{/other_user}","gists_url":"https://api.github.com/users/houndci-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci-bot/subscriptions","organizations_url":"https://api.github.com/users/houndci-bot/orgs","repos_url":"https://api.github.com/users/houndci-bot/repos","events_url":"https://api.github.com/users/houndci-bot/events{/privacy}","received_events_url":"https://api.github.com/users/houndci-bot/received_events","type":"User","site_admin":false},"body":"Redundant curly braces around a hash parameter.","created_at":"2016-12-22T22:40:47Z","updated_at":"2016-12-22T22:40:47Z","html_url":"https://github.com/otwcode/otwarchive/pull/2678#discussion_r93708052","pull_request_url":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678","_links":{"self":{"href":"https://api.github.com/repos/otwcode/otwarchive/pulls/comments/93708052"},"html":{"href":"https://github.com/otwcode/otwarchive/pull/2678#discussion_r93708052"},"pull_request":{"href":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678"}}},"pull_request":{"url":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678","id":99180916,"html_url":"https://github.com/otwcode/otwarchive/pull/2678","diff_url":"https://github.com/otwcode/otwarchive/pull/2678.diff","patch_url":"https://github.com/otwcode/otwarchive/pull/2678.patch","issue_url":"https://api.github.com/repos/otwcode/otwarchive/issues/2678","number":2678,"state":"open","locked":false,"title":"AO3-4722 WorksController 1 - import errors and search param cleansing","user":{"login":"ariana-paris","id":1660785,"avatar_url":"https://avatars.githubusercontent.com/u/1660785?v=3","gravatar_id":"","url":"https://api.github.com/users/ariana-paris","html_url":"https://github.com/ariana-paris","followers_url":"https://api.github.com/users/ariana-paris/followers","following_url":"https://api.github.com/users/ariana-paris/following{/other_user}","gists_url":"https://api.github.com/users/ariana-paris/gists{/gist_id}","starred_url":"https://api.github.com/users/ariana-paris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ariana-paris/subscriptions","organizations_url":"https://api.github.com/users/ariana-paris/orgs","repos_url":"https://api.github.com/users/ariana-paris/repos","events_url":"https://api.github.com/users/ariana-paris/events{/privacy}","received_events_url":"https://api.github.com/users/ariana-paris/received_events","type":"User","site_admin":false},"body":"## Issue\r\n\r\nhttps://otwarchive.atlassian.net/browse/AO3-4722\r\n\r\n## Purpose\r\n\r\nThis is the first of probably a short series of pull requests aiming to increase the WorksController coverage using Rspec instead of Cucumber. The new tests cover:\r\n\r\n- The before_filter for work search parameter cleansing - I found a couple of potential bugs or omissions there, though I don't think they are currently affecting users so I left them alone to avoid scope creep\r\n- The errors returned when performing imports\r\n\r\nCreating some of the new tests uncovered some problems in the API tests (they were making all users in all tests into archivists) and a bug in the StoryParser itself, though one which would only ever affect the tests (no nil check on pseuds, which breaks if there is no current user – but in real life, you can't reach that code without a logged in user). These had to be fixed in order to have sensible WorksController tests, so they are also included in this pull request.\r\n\r\n## Testing\r\n\r\nThese are mainly test changes, as well as one minor refactor in the WorksController and in the StoryParser. Those are both exercised by existing Cucumber tests that I did not touch, so their functionality hasn't changed.\r\n","created_at":"2016-12-22T22:40:35Z","updated_at":"2016-12-22T22:40:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f526114809e54ea80262948c0ba6578e28bd44ff","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678/commits","review_comments_url":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678/comments","review_comment_url":"https://api.github.com/repos/otwcode/otwarchive/pulls/comments{/number}","comments_url":"https://api.github.com/repos/otwcode/otwarchive/issues/2678/comments","statuses_url":"https://api.github.com/repos/otwcode/otwarchive/statuses/0d6fbea5f5dbf253b8362c30fc5a4b80d844becf","head":{"label":"ariana-paris:AO3-4722-Works-controller-rspec-1","ref":"AO3-4722-Works-controller-rspec-1","sha":"0d6fbea5f5dbf253b8362c30fc5a4b80d844becf","user":{"login":"ariana-paris","id":1660785,"avatar_url":"https://avatars.githubusercontent.com/u/1660785?v=3","gravatar_id":"","url":"https://api.github.com/users/ariana-paris","html_url":"https://github.com/ariana-paris","followers_url":"https://api.github.com/users/ariana-paris/followers","following_url":"https://api.github.com/users/ariana-paris/following{/other_user}","gists_url":"https://api.github.com/users/ariana-paris/gists{/gist_id}","starred_url":"https://api.github.com/users/ariana-paris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ariana-paris/subscriptions","organizations_url":"https://api.github.com/users/ariana-paris/orgs","repos_url":"https://api.github.com/users/ariana-paris/repos","events_url":"https://api.github.com/users/ariana-paris/events{/privacy}","received_events_url":"https://api.github.com/users/ariana-paris/received_events","type":"User","site_admin":false},"repo":{"id":4213690,"name":"otwarchive","full_name":"ariana-paris/otwarchive","owner":{"login":"ariana-paris","id":1660785,"avatar_url":"https://avatars.githubusercontent.com/u/1660785?v=3","gravatar_id":"","url":"https://api.github.com/users/ariana-paris","html_url":"https://github.com/ariana-paris","followers_url":"https://api.github.com/users/ariana-paris/followers","following_url":"https://api.github.com/users/ariana-paris/following{/other_user}","gists_url":"https://api.github.com/users/ariana-paris/gists{/gist_id}","starred_url":"https://api.github.com/users/ariana-paris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ariana-paris/subscriptions","organizations_url":"https://api.github.com/users/ariana-paris/orgs","repos_url":"https://api.github.com/users/ariana-paris/repos","events_url":"https://api.github.com/users/ariana-paris/events{/privacy}","received_events_url":"https://api.github.com/users/ariana-paris/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ariana-paris/otwarchive","description":"The Organization for Transformative Works (OTW) - Archive Of Our Own (AO3) Project","fork":true,"url":"https://api.github.com/repos/ariana-paris/otwarchive","forks_url":"https://api.github.com/repos/ariana-paris/otwarchive/forks","keys_url":"https://api.github.com/repos/ariana-paris/otwarchive/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ariana-paris/otwarchive/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ariana-paris/otwarchive/teams","hooks_url":"https://api.github.com/repos/ariana-paris/otwarchive/hooks","issue_events_url":"https://api.github.com/repos/ariana-paris/otwarchive/issues/events{/number}","events_url":"https://api.github.com/repos/ariana-paris/otwarchive/events","assignees_url":"https://api.github.com/repos/ariana-paris/otwarchive/assignees{/user}","branches_url":"https://api.github.com/repos/ariana-paris/otwarchive/branches{/branch}","tags_url":"https://api.github.com/repos/ariana-paris/otwarchive/tags","blobs_url":"https://api.github.com/repos/ariana-paris/otwarchive/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ariana-paris/otwarchive/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ariana-paris/otwarchive/git/refs{/sha}","trees_url":"https://api.github.com/repos/ariana-paris/otwarchive/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ariana-paris/otwarchive/statuses/{sha}","languages_url":"https://api.github.com/repos/ariana-paris/otwarchive/languages","stargazers_url":"https://api.github.com/repos/ariana-paris/otwarchive/stargazers","contributors_url":"https://api.github.com/repos/ariana-paris/otwarchive/contributors","subscribers_url":"https://api.github.com/repos/ariana-paris/otwarchive/subscribers","subscription_url":"https://api.github.com/repos/ariana-paris/otwarchive/subscription","commits_url":"https://api.github.com/repos/ariana-paris/otwarchive/commits{/sha}","git_commits_url":"https://api.github.com/repos/ariana-paris/otwarchive/git/commits{/sha}","comments_url":"https://api.github.com/repos/ariana-paris/otwarchive/comments{/number}","issue_comment_url":"https://api.github.com/repos/ariana-paris/otwarchive/issues/comments{/number}","contents_url":"https://api.github.com/repos/ariana-paris/otwarchive/contents/{+path}","compare_url":"https://api.github.com/repos/ariana-paris/otwarchive/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ariana-paris/otwarchive/merges","archive_url":"https://api.github.com/repos/ariana-paris/otwarchive/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ariana-paris/otwarchive/downloads","issues_url":"https://api.github.com/repos/ariana-paris/otwarchive/issues{/number}","pulls_url":"https://api.github.com/repos/ariana-paris/otwarchive/pulls{/number}","milestones_url":"https://api.github.com/repos/ariana-paris/otwarchive/milestones{/number}","notifications_url":"https://api.github.com/repos/ariana-paris/otwarchive/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ariana-paris/otwarchive/labels{/name}","releases_url":"https://api.github.com/repos/ariana-paris/otwarchive/releases{/id}","deployments_url":"https://api.github.com/repos/ariana-paris/otwarchive/deployments","created_at":"2012-05-03T12:27:42Z","updated_at":"2016-08-29T18:11:53Z","pushed_at":"2016-12-22T16:57:04Z","git_url":"git://github.com/ariana-paris/otwarchive.git","ssh_url":"git@github.com:ariana-paris/otwarchive.git","clone_url":"https://github.com/ariana-paris/otwarchive.git","svn_url":"https://github.com/ariana-paris/otwarchive","homepage":"http://transformativeworks.org/projects/archive","size":52550,"stargazers_count":1,"watchers_count":1,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"otwcode:master","ref":"master","sha":"0cde76cfe6152db3fba76f399388eee06632bec4","user":{"login":"otwcode","id":408606,"avatar_url":"https://avatars.githubusercontent.com/u/408606?v=3","gravatar_id":"","url":"https://api.github.com/users/otwcode","html_url":"https://github.com/otwcode","followers_url":"https://api.github.com/users/otwcode/followers","following_url":"https://api.github.com/users/otwcode/following{/other_user}","gists_url":"https://api.github.com/users/otwcode/gists{/gist_id}","starred_url":"https://api.github.com/users/otwcode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/otwcode/subscriptions","organizations_url":"https://api.github.com/users/otwcode/orgs","repos_url":"https://api.github.com/users/otwcode/repos","events_url":"https://api.github.com/users/otwcode/events{/privacy}","received_events_url":"https://api.github.com/users/otwcode/received_events","type":"Organization","site_admin":false},"repo":{"id":1338040,"name":"otwarchive","full_name":"otwcode/otwarchive","owner":{"login":"otwcode","id":408606,"avatar_url":"https://avatars.githubusercontent.com/u/408606?v=3","gravatar_id":"","url":"https://api.github.com/users/otwcode","html_url":"https://github.com/otwcode","followers_url":"https://api.github.com/users/otwcode/followers","following_url":"https://api.github.com/users/otwcode/following{/other_user}","gists_url":"https://api.github.com/users/otwcode/gists{/gist_id}","starred_url":"https://api.github.com/users/otwcode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/otwcode/subscriptions","organizations_url":"https://api.github.com/users/otwcode/orgs","repos_url":"https://api.github.com/users/otwcode/repos","events_url":"https://api.github.com/users/otwcode/events{/privacy}","received_events_url":"https://api.github.com/users/otwcode/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/otwcode/otwarchive","description":"The Organization for Transformative Works (OTW) - Archive Of Our Own (AO3) Project","fork":false,"url":"https://api.github.com/repos/otwcode/otwarchive","forks_url":"https://api.github.com/repos/otwcode/otwarchive/forks","keys_url":"https://api.github.com/repos/otwcode/otwarchive/keys{/key_id}","collaborators_url":"https://api.github.com/repos/otwcode/otwarchive/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/otwcode/otwarchive/teams","hooks_url":"https://api.github.com/repos/otwcode/otwarchive/hooks","issue_events_url":"https://api.github.com/repos/otwcode/otwarchive/issues/events{/number}","events_url":"https://api.github.com/repos/otwcode/otwarchive/events","assignees_url":"https://api.github.com/repos/otwcode/otwarchive/assignees{/user}","branches_url":"https://api.github.com/repos/otwcode/otwarchive/branches{/branch}","tags_url":"https://api.github.com/repos/otwcode/otwarchive/tags","blobs_url":"https://api.github.com/repos/otwcode/otwarchive/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/otwcode/otwarchive/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/otwcode/otwarchive/git/refs{/sha}","trees_url":"https://api.github.com/repos/otwcode/otwarchive/git/trees{/sha}","statuses_url":"https://api.github.com/repos/otwcode/otwarchive/statuses/{sha}","languages_url":"https://api.github.com/repos/otwcode/otwarchive/languages","stargazers_url":"https://api.github.com/repos/otwcode/otwarchive/stargazers","contributors_url":"https://api.github.com/repos/otwcode/otwarchive/contributors","subscribers_url":"https://api.github.com/repos/otwcode/otwarchive/subscribers","subscription_url":"https://api.github.com/repos/otwcode/otwarchive/subscription","commits_url":"https://api.github.com/repos/otwcode/otwarchive/commits{/sha}","git_commits_url":"https://api.github.com/repos/otwcode/otwarchive/git/commits{/sha}","comments_url":"https://api.github.com/repos/otwcode/otwarchive/comments{/number}","issue_comment_url":"https://api.github.com/repos/otwcode/otwarchive/issues/comments{/number}","contents_url":"https://api.github.com/repos/otwcode/otwarchive/contents/{+path}","compare_url":"https://api.github.com/repos/otwcode/otwarchive/compare/{base}...{head}","merges_url":"https://api.github.com/repos/otwcode/otwarchive/merges","archive_url":"https://api.github.com/repos/otwcode/otwarchive/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/otwcode/otwarchive/downloads","issues_url":"https://api.github.com/repos/otwcode/otwarchive/issues{/number}","pulls_url":"https://api.github.com/repos/otwcode/otwarchive/pulls{/number}","milestones_url":"https://api.github.com/repos/otwcode/otwarchive/milestones{/number}","notifications_url":"https://api.github.com/repos/otwcode/otwarchive/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/otwcode/otwarchive/labels{/name}","releases_url":"https://api.github.com/repos/otwcode/otwarchive/releases{/id}","deployments_url":"https://api.github.com/repos/otwcode/otwarchive/deployments","created_at":"2011-02-07T14:50:58Z","updated_at":"2016-12-18T23:29:10Z","pushed_at":"2016-12-22T22:40:35Z","git_url":"git://github.com/otwcode/otwarchive.git","ssh_url":"git@github.com:otwcode/otwarchive.git","clone_url":"https://github.com/otwcode/otwarchive.git","svn_url":"https://github.com/otwcode/otwarchive","homepage":"http://www.transformativeworks.org/archive_of_our_own/","size":52015,"stargazers_count":228,"watchers_count":228,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":140,"mirror_url":null,"open_issues_count":68,"forks":140,"open_issues":68,"watchers":228,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678"},"html":{"href":"https://github.com/otwcode/otwarchive/pull/2678"},"issue":{"href":"https://api.github.com/repos/otwcode/otwarchive/issues/2678"},"comments":{"href":"https://api.github.com/repos/otwcode/otwarchive/issues/2678/comments"},"review_comments":{"href":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678/comments"},"review_comment":{"href":"https://api.github.com/repos/otwcode/otwarchive/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/otwcode/otwarchive/pulls/2678/commits"},"statuses":{"href":"https://api.github.com/repos/otwcode/otwarchive/statuses/0d6fbea5f5dbf253b8362c30fc5a4b80d844becf"}}}}
{"actor":{"display_login":"houndci-bot"}}