{"action":"created","comment":{"url":"https://api.github.com/repos/C83/THP_2.0/pulls/comments/202790158","pull_request_review_id":137544546,"id":202790158,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMjc5MDE1OA==","diff_hunk":"@@ -0,0 +1,170 @@\n+require 'rails_helper'\n+require 'pry'\n+\n+RSpec.describe LessonsController, type: :controller do\n+  describe 'routes' do\n+    it { should route(:get, '/lessons').to(action: :index) }\n+    it { should route(:get, '/lessons/574d5c29-fd2d-4494-ae28-12cdb0da1c07').to(action: :show, id: \"574d5c29-fd2d-4494-ae28-12cdb0da1c07\") }\n+    it { should route(:post, '/lessons').to(action: :create) }\n+    it { should route(:put, '/lessons/574d5c29-fd2d-4494-ae28-12cdb0da1c07').to(action: :update, id: \"574d5c29-fd2d-4494-ae28-12cdb0da1c07\") }\n+    it { should route(:patch, '/lessons/574d5c29-fd2d-4494-ae28-12cdb0da1c07').to(action: :update, id: \"574d5c29-fd2d-4494-ae28-12cdb0da1c07\") }\n+    it { should route(:delete, '/lessons/574d5c29-fd2d-4494-ae28-12cdb0da1c07').to(action: :destroy, id: \"574d5c29-fd2d-4494-ae28-12cdb0da1c07\") }\n+  end\n+\n+  describe 'GET #index' do\n+    subject do\n+      get :index\n+    end\n+\n+    before do\n+      FactoryBot.create_list(:lesson, 2)\n+      subject\n+    end\n+\n+    it 'returns status 200' do\n+      expect(response.code).to eq(\"200\")\n+    end\n+\n+    it 'lists 2 lessons' do\n+      expect(json_response.count).to eq(2)\n+    end\n+  end\n+\n+  describe 'GET #show' do\n+    let!(:lesson){ FactoryBot.create(:lesson) }\n+    let(:id){ Lesson.last.id }\n+\n+    subject{ get :show, params: { id: id } }\n+\n+    context 'when lesson exist' do\n+      it 'returns status 200' do\n+        subject\n+        expect(response.code).to eq(\"200\")\n+      end\n+      it \"shows the lesson\" do\n+        subject\n+        expect(json_response[:id]).to eq(lesson.id)\n+      end\n+    end\n+\n+    context 'when lesson doesn\\'t exist' do\n+      let(:id){ 1 }\n+      it \"returns error 404\" do\n+        subject\n+        expect(response.code).to eq(\"404\")\n+      end\n+    end\n+  end\n+\n+  describe 'POST #create' do\n+    let(:lesson_params){ FactoryBot.attributes_for(:lesson) }\n+\n+    subject{ post :create, params: { lesson: lesson_params } }\n+\n+    context 'with valid params' do\n+      it 'returns status 201' do\n+        subject\n+        expect(response.code).to eq(\"201\")\n+      end\n+\n+      it 'creates new lesson' do\n+        expect{ subject }.to change{ Lesson.count }.by(1)\n+      end\n+    end\n+\n+    context 'with invalid params' do\n+      it 'returns status 403 without title' do\n+        lesson_params[:title] = ''\n+        subject\n+        expect(response.code).to eq(\"403\")\n+      end\n+      it 'doesn\\'t create new lesson' do\n+        lesson_params[:title] = ''\n+        expect{ subject }.to change { Lesson.count }.by(0)\n+      end\n+      it 'returns status 403 with title so long' do\n+        lesson_params[:title] = Faker::Lorem.characters(51)\n+        subject\n+        expect(response.code).to eq(\"403\")\n+      end\n+      it 'returns status 403 with description so long' do\n+        lesson_params[:description] = Faker::Lorem.characters(301)\n+        subject\n+        expect(response.code).to eq(\"403\")\n+      end\n+      it 'returns status 403 with no title' do\n+        lesson_params[:title] = ''\n+        subject\n+        expect(response.code).to eq(\"403\")\n+      end\n+    end\n+  end\n+\n+  describe 'POST #update' do\n+    let(:lesson) { FactoryBot.create(:lesson, title: 'Arthus') }\n+    let(:new_params){ FactoryBot.attributes_for(:lesson).merge(title: 'Harry') }\n+\n+    subject{ post :update, params: { id: lesson.id, lesson: new_params } }\n+\n+    context 'with valid params' do\n+      before{ subject }\n+      it 'returns status 200' do\n+        expect(response.code).to eq(\"200\")\n+      end\n+      it 'changes the title' do\n+        expect(json_response[:title]).to eq(new_params[:title])\n+      end\n+    end\n+\n+    context 'with invalid params' do\n+      it 'returns status 403 without title' do\n+        new_params[:title] = ''\n+        subject\n+        expect(response.code).to eq(\"403\")\n+      end\n+      it 'returns status 403 with title so long' do\n+        new_params[:title] = Faker::Lorem.characters(51)\n+        subject\n+        expect(response.code).to eq(\"403\")\n+      end\n+      it 'returns status 403 with description so long' do\n+        new_params[:description] = Faker::Lorem.characters(301)\n+        subject\n+        expect(response.code).to eq(\"403\")\n+      end\n+      it 'returns status 403 with no title' do\n+        new_params[:title] = ''\n+        subject\n+        expect(response.code).to eq(\"403\")","path":"spec/controllers/lesson_controller_spec.rb","position":138,"original_position":138,"commit_id":"0c93d068c75550591391fc361fa3dbf7027166e6","original_commit_id":"0c93d068c75550591391fc361fa3dbf7027166e6","user":{"login":"whois-marvin-42","id":35236153,"node_id":"MDQ6VXNlcjM1MjM2MTUz","avatar_url":"https://avatars2.githubusercontent.com/u/35236153?v=4","gravatar_id":"","url":"https://api.github.com/users/whois-marvin-42","html_url":"https://github.com/whois-marvin-42","followers_url":"https://api.github.com/users/whois-marvin-42/followers","following_url":"https://api.github.com/users/whois-marvin-42/following{/other_user}","gists_url":"https://api.github.com/users/whois-marvin-42/gists{/gist_id}","starred_url":"https://api.github.com/users/whois-marvin-42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/whois-marvin-42/subscriptions","organizations_url":"https://api.github.com/users/whois-marvin-42/orgs","repos_url":"https://api.github.com/users/whois-marvin-42/repos","events_url":"https://api.github.com/users/whois-marvin-42/events{/privacy}","received_events_url":"https://api.github.com/users/whois-marvin-42/received_events","type":"User","site_admin":false},"body":"Same as #Using more Rspec builtins","created_at":"2018-07-16T19:05:53Z","updated_at":"2018-07-16T19:32:59Z","html_url":"https://github.com/C83/THP_2.0/pull/17#discussion_r202790158","pull_request_url":"https://api.github.com/repos/C83/THP_2.0/pulls/17","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/C83/THP_2.0/pulls/comments/202790158"},"html":{"href":"https://github.com/C83/THP_2.0/pull/17#discussion_r202790158"},"pull_request":{"href":"https://api.github.com/repos/C83/THP_2.0/pulls/17"}}},"pull_request":{"url":"https://api.github.com/repos/C83/THP_2.0/pulls/17","id":201710856,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAxNzEwODU2","html_url":"https://github.com/C83/THP_2.0/pull/17","diff_url":"https://github.com/C83/THP_2.0/pull/17.diff","patch_url":"https://github.com/C83/THP_2.0/pull/17.patch","issue_url":"https://api.github.com/repos/C83/THP_2.0/issues/17","number":17,"state":"open","locked":false,"title":"Issue09 lesson controller","user":{"login":"C83","id":12127508,"node_id":"MDQ6VXNlcjEyMTI3NTA4","avatar_url":"https://avatars1.githubusercontent.com/u/12127508?v=4","gravatar_id":"","url":"https://api.github.com/users/C83","html_url":"https://github.com/C83","followers_url":"https://api.github.com/users/C83/followers","following_url":"https://api.github.com/users/C83/following{/other_user}","gists_url":"https://api.github.com/users/C83/gists{/gist_id}","starred_url":"https://api.github.com/users/C83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/C83/subscriptions","organizations_url":"https://api.github.com/users/C83/orgs","repos_url":"https://api.github.com/users/C83/repos","events_url":"https://api.github.com/users/C83/events{/privacy}","received_events_url":"https://api.github.com/users/C83/received_events","type":"User","site_admin":false},"body":"# Controller\r\n\r\n### Serializer : \r\nAdd Serializer gem in Gemfile : \r\n```\r\n## Serializer\r\ngem 'active_model_serializers', '~> 0.10.0\r\n```\r\nThen, `bundle install`\r\nGenerating the serializer for lesson model : `rails g serializer lesson`\r\nAfter that, you can specify attributes you want render : \r\n```\r\nattributes :id, :title, :description, :created_at\r\n```\r\nNow, it's easy because we have no association. \r\n\r\n## Routes\r\nWe use the keyword ressources in the `route.rb` file : \r\n``` \r\nresources :lessons, except: [:new, :edit]\r\n```\r\nTesting the last step with `rails routes`\r\n\r\n## Controller \r\nCreate a controller with [this ressource](http://api.rubyonrails.org/classes/ActionController/API.html). As read, ApplicationController is the right controller for API. \r\n\r\n### Error : \r\nWe want that an error raises up when params aren't valid. `create!()` permit that : if validation doesn't work, `ActiveRecord::RecordInvalid: Validation failed:` raises. Place that in `application.rb` file : \r\n```\r\n  # Two errors catched : RecordInvalid and ParameterMissing\r\n  rescue_from ActiveRecord::RecordInvalid, ActionController::ParameterMissing, with: :show_errors\r\n\r\n  def show_errors(exception)\r\n    render json: exception, status: 403\r\n  end\r\n```\r\n\r\n### Render :\r\nTo return, use `render json: object, status number`. \r\nReplace with the correct object who has a serializer. Add the correspondent status (the number or the name). \r\n\r\n## Test controller : \r\nSome tips : \r\n- creating some lessons with `FactoryBot.create_list(:lesson, 2)`. But to test index method, no need creates few dozens of lessons. Just two are sufficient. \r\n- `it { should route(:get, '/lessons').to(action: :index) }` to test each route with the url and the name of method in the controller. \r\n- `expect(response.code).to eq(\"200\")` to test the response code.\r\n- use variables with let (lazy utilisation) and let! (behavior like `before`)\r\n- use `subject`\r\n- describing with keywords `describe` which contains `context` 's\r\n\r\n\r\nCloses #9 ","created_at":"2018-07-16T17:57:29Z","updated_at":"2018-07-16T19:33:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a6c8f535dbc404b44afaa3b11a5180a32f1608a2","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/C83/THP_2.0/pulls/17/commits","review_comments_url":"https://api.github.com/repos/C83/THP_2.0/pulls/17/comments","review_comment_url":"https://api.github.com/repos/C83/THP_2.0/pulls/comments{/number}","comments_url":"https://api.github.com/repos/C83/THP_2.0/issues/17/comments","statuses_url":"https://api.github.com/repos/C83/THP_2.0/statuses/0c93d068c75550591391fc361fa3dbf7027166e6","head":{"label":"C83:Issue09_Lesson_Controller","ref":"Issue09_Lesson_Controller","sha":"0c93d068c75550591391fc361fa3dbf7027166e6","user":{"login":"C83","id":12127508,"node_id":"MDQ6VXNlcjEyMTI3NTA4","avatar_url":"https://avatars1.githubusercontent.com/u/12127508?v=4","gravatar_id":"","url":"https://api.github.com/users/C83","html_url":"https://github.com/C83","followers_url":"https://api.github.com/users/C83/followers","following_url":"https://api.github.com/users/C83/following{/other_user}","gists_url":"https://api.github.com/users/C83/gists{/gist_id}","starred_url":"https://api.github.com/users/C83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/C83/subscriptions","organizations_url":"https://api.github.com/users/C83/orgs","repos_url":"https://api.github.com/users/C83/repos","events_url":"https://api.github.com/users/C83/events{/privacy}","received_events_url":"https://api.github.com/users/C83/received_events","type":"User","site_admin":false},"repo":{"id":139450154,"node_id":"MDEwOlJlcG9zaXRvcnkxMzk0NTAxNTQ=","name":"THP_2.0","full_name":"C83/THP_2.0","owner":{"login":"C83","id":12127508,"node_id":"MDQ6VXNlcjEyMTI3NTA4","avatar_url":"https://avatars1.githubusercontent.com/u/12127508?v=4","gravatar_id":"","url":"https://api.github.com/users/C83","html_url":"https://github.com/C83","followers_url":"https://api.github.com/users/C83/followers","following_url":"https://api.github.com/users/C83/following{/other_user}","gists_url":"https://api.github.com/users/C83/gists{/gist_id}","starred_url":"https://api.github.com/users/C83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/C83/subscriptions","organizations_url":"https://api.github.com/users/C83/orgs","repos_url":"https://api.github.com/users/C83/repos","events_url":"https://api.github.com/users/C83/events{/privacy}","received_events_url":"https://api.github.com/users/C83/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/C83/THP_2.0","description":null,"fork":false,"url":"https://api.github.com/repos/C83/THP_2.0","forks_url":"https://api.github.com/repos/C83/THP_2.0/forks","keys_url":"https://api.github.com/repos/C83/THP_2.0/keys{/key_id}","collaborators_url":"https://api.github.com/repos/C83/THP_2.0/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/C83/THP_2.0/teams","hooks_url":"https://api.github.com/repos/C83/THP_2.0/hooks","issue_events_url":"https://api.github.com/repos/C83/THP_2.0/issues/events{/number}","events_url":"https://api.github.com/repos/C83/THP_2.0/events","assignees_url":"https://api.github.com/repos/C83/THP_2.0/assignees{/user}","branches_url":"https://api.github.com/repos/C83/THP_2.0/branches{/branch}","tags_url":"https://api.github.com/repos/C83/THP_2.0/tags","blobs_url":"https://api.github.com/repos/C83/THP_2.0/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/C83/THP_2.0/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/C83/THP_2.0/git/refs{/sha}","trees_url":"https://api.github.com/repos/C83/THP_2.0/git/trees{/sha}","statuses_url":"https://api.github.com/repos/C83/THP_2.0/statuses/{sha}","languages_url":"https://api.github.com/repos/C83/THP_2.0/languages","stargazers_url":"https://api.github.com/repos/C83/THP_2.0/stargazers","contributors_url":"https://api.github.com/repos/C83/THP_2.0/contributors","subscribers_url":"https://api.github.com/repos/C83/THP_2.0/subscribers","subscription_url":"https://api.github.com/repos/C83/THP_2.0/subscription","commits_url":"https://api.github.com/repos/C83/THP_2.0/commits{/sha}","git_commits_url":"https://api.github.com/repos/C83/THP_2.0/git/commits{/sha}","comments_url":"https://api.github.com/repos/C83/THP_2.0/comments{/number}","issue_comment_url":"https://api.github.com/repos/C83/THP_2.0/issues/comments{/number}","contents_url":"https://api.github.com/repos/C83/THP_2.0/contents/{+path}","compare_url":"https://api.github.com/repos/C83/THP_2.0/compare/{base}...{head}","merges_url":"https://api.github.com/repos/C83/THP_2.0/merges","archive_url":"https://api.github.com/repos/C83/THP_2.0/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/C83/THP_2.0/downloads","issues_url":"https://api.github.com/repos/C83/THP_2.0/issues{/number}","pulls_url":"https://api.github.com/repos/C83/THP_2.0/pulls{/number}","milestones_url":"https://api.github.com/repos/C83/THP_2.0/milestones{/number}","notifications_url":"https://api.github.com/repos/C83/THP_2.0/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/C83/THP_2.0/labels{/name}","releases_url":"https://api.github.com/repos/C83/THP_2.0/releases{/id}","deployments_url":"https://api.github.com/repos/C83/THP_2.0/deployments","created_at":"2018-07-02T13:50:25Z","updated_at":"2018-07-12T14:28:18Z","pushed_at":"2018-07-16T17:57:30Z","git_url":"git://github.com/C83/THP_2.0.git","ssh_url":"git@github.com:C83/THP_2.0.git","clone_url":"https://github.com/C83/THP_2.0.git","svn_url":"https://github.com/C83/THP_2.0","homepage":null,"size":59,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":2,"license":null,"forks":0,"open_issues":2,"watchers":0,"default_branch":"master"}},"base":{"label":"C83:master","ref":"master","sha":"f7026b6fcf8e3537e064c9d110242e24e11a3664","user":{"login":"C83","id":12127508,"node_id":"MDQ6VXNlcjEyMTI3NTA4","avatar_url":"https://avatars1.githubusercontent.com/u/12127508?v=4","gravatar_id":"","url":"https://api.github.com/users/C83","html_url":"https://github.com/C83","followers_url":"https://api.github.com/users/C83/followers","following_url":"https://api.github.com/users/C83/following{/other_user}","gists_url":"https://api.github.com/users/C83/gists{/gist_id}","starred_url":"https://api.github.com/users/C83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/C83/subscriptions","organizations_url":"https://api.github.com/users/C83/orgs","repos_url":"https://api.github.com/users/C83/repos","events_url":"https://api.github.com/users/C83/events{/privacy}","received_events_url":"https://api.github.com/users/C83/received_events","type":"User","site_admin":false},"repo":{"id":139450154,"node_id":"MDEwOlJlcG9zaXRvcnkxMzk0NTAxNTQ=","name":"THP_2.0","full_name":"C83/THP_2.0","owner":{"login":"C83","id":12127508,"node_id":"MDQ6VXNlcjEyMTI3NTA4","avatar_url":"https://avatars1.githubusercontent.com/u/12127508?v=4","gravatar_id":"","url":"https://api.github.com/users/C83","html_url":"https://github.com/C83","followers_url":"https://api.github.com/users/C83/followers","following_url":"https://api.github.com/users/C83/following{/other_user}","gists_url":"https://api.github.com/users/C83/gists{/gist_id}","starred_url":"https://api.github.com/users/C83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/C83/subscriptions","organizations_url":"https://api.github.com/users/C83/orgs","repos_url":"https://api.github.com/users/C83/repos","events_url":"https://api.github.com/users/C83/events{/privacy}","received_events_url":"https://api.github.com/users/C83/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/C83/THP_2.0","description":null,"fork":false,"url":"https://api.github.com/repos/C83/THP_2.0","forks_url":"https://api.github.com/repos/C83/THP_2.0/forks","keys_url":"https://api.github.com/repos/C83/THP_2.0/keys{/key_id}","collaborators_url":"https://api.github.com/repos/C83/THP_2.0/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/C83/THP_2.0/teams","hooks_url":"https://api.github.com/repos/C83/THP_2.0/hooks","issue_events_url":"https://api.github.com/repos/C83/THP_2.0/issues/events{/number}","events_url":"https://api.github.com/repos/C83/THP_2.0/events","assignees_url":"https://api.github.com/repos/C83/THP_2.0/assignees{/user}","branches_url":"https://api.github.com/repos/C83/THP_2.0/branches{/branch}","tags_url":"https://api.github.com/repos/C83/THP_2.0/tags","blobs_url":"https://api.github.com/repos/C83/THP_2.0/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/C83/THP_2.0/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/C83/THP_2.0/git/refs{/sha}","trees_url":"https://api.github.com/repos/C83/THP_2.0/git/trees{/sha}","statuses_url":"https://api.github.com/repos/C83/THP_2.0/statuses/{sha}","languages_url":"https://api.github.com/repos/C83/THP_2.0/languages","stargazers_url":"https://api.github.com/repos/C83/THP_2.0/stargazers","contributors_url":"https://api.github.com/repos/C83/THP_2.0/contributors","subscribers_url":"https://api.github.com/repos/C83/THP_2.0/subscribers","subscription_url":"https://api.github.com/repos/C83/THP_2.0/subscription","commits_url":"https://api.github.com/repos/C83/THP_2.0/commits{/sha}","git_commits_url":"https://api.github.com/repos/C83/THP_2.0/git/commits{/sha}","comments_url":"https://api.github.com/repos/C83/THP_2.0/comments{/number}","issue_comment_url":"https://api.github.com/repos/C83/THP_2.0/issues/comments{/number}","contents_url":"https://api.github.com/repos/C83/THP_2.0/contents/{+path}","compare_url":"https://api.github.com/repos/C83/THP_2.0/compare/{base}...{head}","merges_url":"https://api.github.com/repos/C83/THP_2.0/merges","archive_url":"https://api.github.com/repos/C83/THP_2.0/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/C83/THP_2.0/downloads","issues_url":"https://api.github.com/repos/C83/THP_2.0/issues{/number}","pulls_url":"https://api.github.com/repos/C83/THP_2.0/pulls{/number}","milestones_url":"https://api.github.com/repos/C83/THP_2.0/milestones{/number}","notifications_url":"https://api.github.com/repos/C83/THP_2.0/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/C83/THP_2.0/labels{/name}","releases_url":"https://api.github.com/repos/C83/THP_2.0/releases{/id}","deployments_url":"https://api.github.com/repos/C83/THP_2.0/deployments","created_at":"2018-07-02T13:50:25Z","updated_at":"2018-07-12T14:28:18Z","pushed_at":"2018-07-16T17:57:30Z","git_url":"git://github.com/C83/THP_2.0.git","ssh_url":"git@github.com:C83/THP_2.0.git","clone_url":"https://github.com/C83/THP_2.0.git","svn_url":"https://github.com/C83/THP_2.0","homepage":null,"size":59,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":2,"license":null,"forks":0,"open_issues":2,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/C83/THP_2.0/pulls/17"},"html":{"href":"https://github.com/C83/THP_2.0/pull/17"},"issue":{"href":"https://api.github.com/repos/C83/THP_2.0/issues/17"},"comments":{"href":"https://api.github.com/repos/C83/THP_2.0/issues/17/comments"},"review_comments":{"href":"https://api.github.com/repos/C83/THP_2.0/pulls/17/comments"},"review_comment":{"href":"https://api.github.com/repos/C83/THP_2.0/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/C83/THP_2.0/pulls/17/commits"},"statuses":{"href":"https://api.github.com/repos/C83/THP_2.0/statuses/0c93d068c75550591391fc361fa3dbf7027166e6"}},"author_association":"OWNER"}}
{"actor":{"display_login":"whois-marvin-42"}}