Browse Source

#215 テスト・ケース追加

pull/219/head
みてるぞ 1 month ago
parent
commit
ae9cba5fbe
3 changed files with 248 additions and 10 deletions
  1. +2
    -2
      backend/spec/requests/posts_spec.rb
  2. +31
    -5
      backend/spec/requests/tags_spec.rb
  3. +215
    -3
      backend/spec/requests/wiki_spec.rb

+ 2
- 2
backend/spec/requests/posts_spec.rb View File

@@ -15,11 +15,11 @@ RSpec.describe 'Posts API', type: :request do
expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)


expect(json).to have_key('posts') expect(json).to have_key('posts')
expect(json['posts']).to be_a(Array)
expect(json['posts']).to be_an(Array)
expect(json['posts']).not_to be_empty expect(json['posts']).not_to be_empty


tags = json['posts'][0]['tags'] tags = json['posts'][0]['tags']
expect(tags).to be_a(Array)
expect(tags).to be_an(Array)
expect(tags).not_to be_empty expect(tags).not_to be_empty


expect(tags[0]).to have_key('name') expect(tags[0]).to have_key('name')


+ 31
- 5
backend/spec/requests/tags_spec.rb View File

@@ -11,23 +11,50 @@ RSpec.describe 'Tags API', type: :request do
get '/tags' get '/tags'


expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)


expect(json).to be_a(Array)
expect(json).to be_an(Array)
expect(json).not_to be_empty expect(json).not_to be_empty
expect(json[0]).to have_key('name') expect(json[0]).to have_key('name')
expect(json.map { |t| t['name'] }).to include('spec_tag') expect(json.map { |t| t['name'] }).to include('spec_tag')
end end
end end


describe 'GET /tags/:id' do
subject(:request) do
get "/tags/#{ tag_id }"
end

let(:tag_id) { tag.id }

context 'when tag exists' do
it 'returns tag with name' do
request
expect(response).to have_http_status(:ok)

expect(json).to include(
'id' => tag.id,
'name' => 'spec_tag',
'category' => 'general')
end
end

context 'when tag does not exist' do
let(:tag_id) { 9_999_999 }

it 'returns 404' do
request
expect(response).to have_http_status(:not_found)
end
end
end

describe 'GET /tags/autocomplete' do describe 'GET /tags/autocomplete' do
it 'returns matching tags by q' do it 'returns matching tags by q' do
get '/tags/autocomplete', params: { q: 'spec' } get '/tags/autocomplete', params: { q: 'spec' }


expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)


expect(json).to be_a(Array)
expect(json).to be_an(Array)
expect(json.map { |t| t['name'] }).to include('spec_tag') expect(json.map { |t| t['name'] }).to include('spec_tag')
end end
end end
@@ -37,7 +64,6 @@ RSpec.describe 'Tags API', type: :request do
get "/tags/name/#{ CGI.escape('spec_tag') }" get "/tags/name/#{ CGI.escape('spec_tag') }"


expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)


expect(json).to have_key('id') expect(json).to have_key('id')
expect(json).to have_key('name') expect(json).to have_key('name')


+ 215
- 3
backend/spec/requests/wiki_spec.rb View File

@@ -16,9 +16,8 @@ RSpec.describe 'Wiki API', type: :request do
get '/wiki' get '/wiki'


expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)


expect(json).to be_a(Array)
expect(json).to be_an(Array)
expect(json).not_to be_empty expect(json).not_to be_empty


expect(json[0]).to have_key('title') expect(json[0]).to have_key('title')
@@ -26,12 +25,225 @@ RSpec.describe 'Wiki API', type: :request do
end end
end end


describe 'GET /wiki/:id' do
subject(:request) do
get "/wiki/#{ page_id }"
end

let(:page_id) { page.id }

context 'when wiki page exists' do
it 'returns wiki page with title' do
request
expect(response).to have_http_status(:ok)

expect(json).to include(
'id' => page.id,
'title' => 'spec_wiki_title')
end
end

context 'when wiki page does not exist' do
let(:page_id) { 9_999_999 }

it 'returns 404' do
request
expect(response).to have_http_status(:not_found)
end
end
end

describe 'POST /wiki' do
let(:endpoint) { '/wiki' }

let(:member) { create(:user, role: 'member') }
let(:guest) { create(:user, role: 'guest') }

def auth_headers(user)
{ 'X-Transfer-Code' => user.inheritance_code }
end

context 'when not logged in' do
it 'returns 401' do
post endpoint, params: { title: 'Test', body: 'Hello' }
expect(response).to have_http_status(:unauthorized)
end
end

context 'when logged in but not member' do
it 'returns 403' do
post endpoint, params: { title: 'Test', body: 'Hello' }, headers: auth_headers(guest)
expect(response).to have_http_status(:forbidden)
end
end

context 'when params invalid' do
it 'returns 422 when title blank' do
post endpoint, params: { title: '', body: 'Hello' }, headers: auth_headers(member)
expect(response).to have_http_status(:unprocessable_entity)
end

it 'returns 422 when body blank' do
post endpoint, params: { title: 'Test', body: '' }, headers: auth_headers(member)
expect(response).to have_http_status(:unprocessable_entity)
end
end

context 'when success' do
it 'creates wiki_page and first content revision' do
expect do
post endpoint, params: { title: 'TestPage', body: "a\nb\nc", message: 'init' },
headers: auth_headers(member)
end
.to change(WikiPage, :count).by(1)
.and change(WikiRevision, :count).by(1)

expect(response).to have_http_status(:created)

page_id = json.fetch('id')
expect(json.fetch('title')).to eq('TestPage')

page = WikiPage.find(page_id)
rev = page.current_revision
expect(rev).to be_present
expect(rev).to be_content
expect(rev.message).to eq('init')

# body が復元できること
expect(page.body).to eq("a\nb\nc")

# 行数とリレーションの整合
expect(rev.lines_count).to eq(3)
expect(rev.wiki_revision_lines.order(:position).pluck(:position)).to eq([0, 1, 2])
expect(rev.wiki_lines.pluck(:body)).to match_array(%w[a b c])
end

it 'reuses existing WikiLine rows by sha256' do
# 先に同じ行を作っておく
WikiLine.create!(sha256: Digest::SHA256.hexdigest('a'), body: 'a', created_at: Time.current, updated_at: Time.current)

post endpoint,
params: { title: 'Reuse', body: "a\na" },
headers: auth_headers(member)

page = WikiPage.find(JSON.parse(response.body).fetch('id'))
rev = page.current_revision
expect(rev.lines_count).to eq(2)

# "a" の WikiLine が増殖しない(1行のはず)
expect(WikiLine.where(body: 'a').count).to eq(1)
end
end
end

describe 'PUT /wiki/:id' do
let(:member) { create(:user, role: 'member', inheritance_code: SecureRandom.hex(16)) }
let(:guest) { create(:user, role: 'guest', inheritance_code: SecureRandom.hex(16)) }

def auth_headers(user)
{ 'X-Transfer-Code' => user.inheritance_code }
end

#let!(:page) { create(:wiki_page, title: 'TestPage') }
let!(:page) do
build(:wiki_page, title: 'TestPage').tap do |p|
puts p.errors.full_messages unless p.valid?
p.save!
end
end

before do
# 初期版を 1 つ作っておく(更新が“2版目”になるように)
Wiki::Commit.content!(page: page, body: "a\nb", created_user: member, message: 'init')
end

context 'when not logged in' do
it 'returns 401' do
put "/wiki/#{page.id}", params: { title: 'TestPage', body: 'x' }
expect(response).to have_http_status(:unauthorized)
end
end

context 'when logged in but not member' do
it 'returns 403' do
put "/wiki/#{page.id}",
params: { title: 'TestPage', body: 'x' },
headers: auth_headers(guest)
expect(response).to have_http_status(:forbidden)
end
end

context 'when params invalid' do
it 'returns 422 when body blank' do
put "/wiki/#{page.id}",
params: { title: 'TestPage', body: '' },
headers: auth_headers(member)
expect(response).to have_http_status(:unprocessable_entity)
end

it 'returns 422 when title mismatched (if you forbid rename here)' do
put "/wiki/#{page.id}",
params: { title: 'OtherTitle', body: 'x' },
headers: auth_headers(member)
# 君の controller 例だと title 変更は 422 にしてた
expect(response).to have_http_status(:unprocessable_entity)
end
end

context 'when success' do
it 'creates new revision and returns 200' do
current_id = page.wiki_revisions.maximum(:id)

expect do
put "/wiki/#{page.id}",
params: { title: 'TestPage', body: "x\ny", message: 'edit', base_revision_id: current_id },
headers: auth_headers(member)
end.to change(WikiRevision, :count).by(1)

expect(response).to have_http_status(:ok)

page.reload
rev = page.current_revision
expect(rev).to be_content
expect(rev.message).to eq('edit')
expect(page.body).to eq("x\ny")
expect(rev.base_revision_id).to eq(current_id)
end
end

# TODO: コンフリクト未実装のため,実装したらコメント外す.
# context 'when conflict' do
# it 'returns 409 when base_revision_id mismatches' do
# # 先に別ユーザ(同じ member でもOK)が 1 回更新して先頭を進める
# Wiki::Commit.content!(page: page, body: "zzz", created_user: member, message: 'other edit')
# page.reload

# stale_id = page.wiki_revisions.order(:id).first.id # わざと古い id
# put "/wiki/#{page.id}",
# params: { title: 'TestPage', body: 'x', base_revision_id: stale_id },
# headers: auth_headers(member)

# expect(response).to have_http_status(:conflict)
# json = JSON.parse(response.body)
# expect(json['error']).to eq('conflict')
# end
# end

context 'when page not found' do
it 'returns 404' do
put "/wiki/99999999",
params: { title: 'X', body: 'x' },
headers: auth_headers(member)
expect(response).to have_http_status(:not_found)
end
end
end

describe 'GET /wiki/title/:title' do describe 'GET /wiki/title/:title' do
it 'returns wiki page by title' do it 'returns wiki page by title' do
get "/wiki/title/#{CGI.escape('spec_wiki_title')}" get "/wiki/title/#{CGI.escape('spec_wiki_title')}"


expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)


expect(json).to have_key('id') expect(json).to have_key('id')
expect(json).to have_key('title') expect(json).to have_key('title')


Loading…
Cancel
Save