refactor routes

This commit is contained in:
Pig Fang 2020-05-29 09:09:10 +08:00
parent f36852a24b
commit 6f55045f9e
8 changed files with 68 additions and 88 deletions

View File

@ -25,7 +25,7 @@ export default async function addClosetItem(
}
const { code, message } = await fetch.post<fetch.ResponseBody>(
'/user/closet/add',
'/user/closet',
{ tid: texture.tid, name },
)
if (code === 0) {

View File

@ -105,8 +105,8 @@ const Closet: React.FC = () => {
return
}
const { code, message } = await fetch.post<fetch.ResponseBody>(
`/user/closet/rename/${item.tid}`,
const { code, message } = await fetch.put<fetch.ResponseBody>(
`/user/closet/${item.tid}`,
{ name },
)
if (code === 0) {

View File

@ -12,8 +12,8 @@ export default async function removeClosetItem(tid: number): Promise<boolean> {
return false
}
const { code, message } = await fetch.post<fetch.ResponseBody>(
`/user/closet/remove/${tid}`,
const { code, message } = await fetch.del<fetch.ResponseBody>(
`/user/closet/${tid}`,
)
if (code === 0) {
toast.success(message)

View File

@ -376,7 +376,7 @@ describe('add to closet', () => {
})
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith('/user/closet/add', {
expect(fetch.post).toBeCalledWith('/user/closet', {
tid: fixtureSkin.tid,
name: 't',
}),
@ -400,7 +400,7 @@ describe('add to closet', () => {
})
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith('/user/closet/add', {
expect(fetch.post).toBeCalledWith('/user/closet', {
tid: fixtureSkin.tid,
name: 't',
}),
@ -419,7 +419,7 @@ describe('remove from closet', () => {
})
it('succeeded', async () => {
fetch.post.mockResolvedValue({ code: 0, message: 'ok' })
fetch.del.mockResolvedValue({ code: 0, message: 'ok' })
const { getByText, getByRole, queryByText } = render(<Show />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
@ -427,9 +427,7 @@ describe('remove from closet', () => {
fireEvent.click(getByText(t('skinlib.removeFromCloset')))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith(
`/user/closet/remove/${fixtureSkin.tid}`,
),
expect(fetch.del).toBeCalledWith(`/user/closet/${fixtureSkin.tid}`),
)
expect(queryByText('ok')).toBeInTheDocument()
expect(getByRole('status')).toHaveClass('alert-success')
@ -437,7 +435,7 @@ describe('remove from closet', () => {
})
it('failed', async () => {
fetch.post.mockResolvedValue({ code: 1, message: 'failed' })
fetch.del.mockResolvedValue({ code: 1, message: 'failed' })
const { getByText, getByRole, queryByText } = render(<Show />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
@ -445,9 +443,7 @@ describe('remove from closet', () => {
fireEvent.click(getByText(t('skinlib.removeFromCloset')))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith(
`/user/closet/remove/${fixtureSkin.tid}`,
),
expect(fetch.del).toBeCalledWith(`/user/closet/${fixtureSkin.tid}`),
)
expect(queryByText('failed')).toBeInTheDocument()
expect(getByRole('alert')).toHaveClass('alert-danger')

View File

@ -391,26 +391,26 @@ describe('remove from closet', () => {
})
it('succeeded', async () => {
fetch.post.mockResolvedValue({ code: 0, message: 'ok' })
fetch.del.mockResolvedValue({ code: 0, message: 'ok' })
const { getByText, queryByText } = render(<SkinLibrary />)
await waitFor(() => expect(fetch.get).toBeCalled())
fireEvent.click(getByText(fixtureItem.likes.toString()))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() => expect(fetch.post).toBeCalled())
await waitFor(() => expect(fetch.del).toBeCalled())
expect(queryByText((fixtureItem.likes - 1).toString())).toBeInTheDocument()
})
it('failed', async () => {
fetch.post.mockResolvedValue({ code: 1, message: 'failed' })
fetch.del.mockResolvedValue({ code: 1, message: 'failed' })
const { getByText, queryByText } = render(<SkinLibrary />)
await waitFor(() => expect(fetch.get).toBeCalled())
fireEvent.click(getByText(fixtureItem.likes.toString()))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() => expect(fetch.post).toBeCalled())
await waitFor(() => expect(fetch.del).toBeCalled())
expect(queryByText(fixtureItem.likes.toString())).toBeInTheDocument()
})
})

View File

@ -129,7 +129,7 @@ describe('rename item', () => {
})
it('succeeded', async () => {
fetch.post.mockResolvedValue({ code: 0, message: 'success' })
fetch.put.mockResolvedValue({ code: 0, message: 'success' })
const { getByText, getByDisplayValue, getByRole, queryByText } = render(
<Closet />,
@ -142,12 +142,9 @@ describe('rename item', () => {
})
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith(
`/user/closet/rename/${fixtureSkin.tid}`,
{
name: 'my skin',
},
),
expect(fetch.put).toBeCalledWith(`/user/closet/${fixtureSkin.tid}`, {
name: 'my skin',
}),
)
expect(queryByText('my skin')).toBeInTheDocument()
expect(queryByText('success')).toBeInTheDocument()
@ -155,8 +152,6 @@ describe('rename item', () => {
})
it('empty name', async () => {
fetch.post.mockResolvedValue({ code: 0, message: 'success' })
const { getByText, getByDisplayValue, queryByText } = render(<Closet />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
@ -165,14 +160,14 @@ describe('rename item', () => {
target: { value: '' },
})
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() => expect(fetch.post).not.toBeCalled())
await waitFor(() => expect(fetch.put).not.toBeCalled())
expect(queryByText(t('skinlib.emptyNewTextureName'))).toBeInTheDocument()
fireEvent.click(getByText(t('general.cancel')))
})
it('failed', async () => {
fetch.post.mockResolvedValue({ code: 1, message: 'failed' })
fetch.put.mockResolvedValue({ code: 1, message: 'failed' })
const { getByText, getByDisplayValue, getByRole, queryByText } = render(
<Closet />,
@ -185,30 +180,14 @@ describe('rename item', () => {
})
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith(
`/user/closet/rename/${fixtureSkin.tid}`,
{
name: 'my skin',
},
),
expect(fetch.put).toBeCalledWith(`/user/closet/${fixtureSkin.tid}`, {
name: 'my skin',
}),
)
expect(queryByText(fixtureSkin.pivot.item_name)).toBeInTheDocument()
expect(queryByText('failed')).toBeInTheDocument()
expect(getByRole('alert')).toHaveClass('alert-danger')
})
it('cancelled', async () => {
const { getByText, getByDisplayValue, queryByText } = render(<Closet />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getByText(t('user.renameItem')))
fireEvent.input(getByDisplayValue(fixtureSkin.pivot.item_name), {
target: { value: 'my skin' },
})
fireEvent.click(getByText(t('general.cancel')))
await waitFor(() => expect(fetch.post).not.toBeCalled())
expect(queryByText(fixtureSkin.pivot.item_name)).toBeInTheDocument()
})
})
describe('remove item', () => {
@ -217,7 +196,7 @@ describe('remove item', () => {
})
it('succeeded', async () => {
fetch.post.mockResolvedValue({ code: 0, message: 'success' })
fetch.del.mockResolvedValue({ code: 0, message: 'success' })
const { getByText, getByRole, queryByText } = render(<Closet />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
@ -225,9 +204,7 @@ describe('remove item', () => {
fireEvent.click(getByText(t('user.removeItem')))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith(
`/user/closet/remove/${fixtureSkin.tid}`,
),
expect(fetch.del).toBeCalledWith(`/user/closet/${fixtureSkin.tid}`),
)
expect(queryByText(/skin library/i)).toBeInTheDocument()
expect(queryByText('success')).toBeInTheDocument()
@ -235,7 +212,7 @@ describe('remove item', () => {
})
it('failed', async () => {
fetch.post.mockResolvedValue({ code: 1, message: 'failed' })
fetch.del.mockResolvedValue({ code: 1, message: 'failed' })
const { getByText, getByRole, queryByText } = render(<Closet />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
@ -243,9 +220,7 @@ describe('remove item', () => {
fireEvent.click(getByText(t('user.removeItem')))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
expect(fetch.post).toBeCalledWith(
`/user/closet/remove/${fixtureSkin.tid}`,
),
expect(fetch.del).toBeCalledWith(`/user/closet/${fixtureSkin.tid}`),
)
expect(queryByText(fixtureSkin.pivot.item_name)).toBeInTheDocument()
expect(queryByText('failed')).toBeInTheDocument()
@ -258,7 +233,7 @@ describe('remove item', () => {
fireEvent.click(getByText(t('user.removeItem')))
fireEvent.click(getByText(t('general.cancel')))
await waitFor(() => expect(fetch.post).not.toBeCalled())
await waitFor(() => expect(fetch.del).not.toBeCalled())
expect(queryByText(fixtureSkin.pivot.item_name)).toBeInTheDocument()
})
})

View File

@ -84,9 +84,9 @@ Route::prefix('user')
Route::get('', 'ClosetController@index')->name('page');
Route::get('list', 'ClosetController@getClosetData')->name('list');
Route::get('ids', 'ClosetController@allIds')->name('ids');
Route::post('add', 'ClosetController@add')->name('add');
Route::post('remove/{tid}', 'ClosetController@remove')->name('remove');
Route::post('rename/{tid}', 'ClosetController@rename')->name('rename');
Route::post('', 'ClosetController@add')->name('add');
Route::put('{tid}', 'ClosetController@rename')->name('rename');
Route::delete('{tid}', 'ClosetController@remove')->name('remove');
});
// OAuth2 Management

View File

@ -88,17 +88,18 @@ class ClosetControllerTest extends TestCase
option(['score_per_closet_item' => 10]);
// missing `tid` field
$this->postJson('/user/closet/add')->assertJsonValidationErrors('tid');
$this->postJson(route('user.closet.add'))
->assertJsonValidationErrors('tid');
// `tid` is not a integer
$this->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => 'string']
)->assertJsonValidationErrors('tid');
// missing `name` field
$this->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => 0]
)->assertJsonValidationErrors('name');
@ -114,7 +115,7 @@ class ClosetControllerTest extends TestCase
}
);
$this->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => $texture->tid, 'name' => $name]
)->assertJson(['code' => 1, 'message' => 'rejected']);
$filter->assertApplied(
@ -142,7 +143,7 @@ class ClosetControllerTest extends TestCase
$this->user->score = 0;
$this->user->save();
$this->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => $texture->tid, 'name' => $name]
)->assertJson([
'code' => 1,
@ -153,7 +154,7 @@ class ClosetControllerTest extends TestCase
$this->user->score = 100;
$this->user->save();
$this->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => -1, 'name' => 'my']
)->assertJson([
'code' => 1,
@ -167,7 +168,7 @@ class ClosetControllerTest extends TestCase
'uploader' => $uploader->uid + 1,
]);
$this->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => $privateTexture->tid, 'name' => $name]
)->assertJson([
'code' => 1,
@ -180,7 +181,7 @@ class ClosetControllerTest extends TestCase
]);
$this->actingAs(factory(User::class)->state('admin')->create())
->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => $privateTexture->tid, 'name' => $name]
)->assertJson([
'code' => 0,
@ -191,7 +192,7 @@ class ClosetControllerTest extends TestCase
Event::fake();
$this->actingAs($this->user)
->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => $texture->tid, 'name' => $name]
)->assertJson([
'code' => 0,
@ -224,7 +225,7 @@ class ClosetControllerTest extends TestCase
// if the texture is duplicated, should be warned
$this->postJson(
'/user/closet/add',
route('user.closet.add'),
['tid' => $texture->tid, 'name' => $name]
)->assertJson([
'code' => 1,
@ -239,7 +240,8 @@ class ClosetControllerTest extends TestCase
$name = 'new';
// missing `name` field
$this->postJson('/user/closet/rename/0')->assertJsonValidationErrors('name');
$this->putJson(route('user.closet.rename', ['tid' => 0]))
->assertJsonValidationErrors('name');
// rejection
$filter = Fakes\Filter::fake();
@ -253,8 +255,10 @@ class ClosetControllerTest extends TestCase
}
);
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$this->postJson('/user/closet/rename/'.$texture->tid, ['name' => $name])
->assertJson(['code' => 1, 'message' => 'rejected']);
$this->putJson(
route('user.closet.rename', ['tid' => $texture->tid]),
['name' => $name]
)->assertJson(['code' => 1, 'message' => 'rejected']);
$filter->assertApplied(
'rename_closet_item_name',
function ($itemName, $tid) use ($name, $texture) {
@ -278,20 +282,24 @@ class ClosetControllerTest extends TestCase
// rename a not-existed texture
Fakes\Filter::fake();
$this->postJson('/user/closet/rename/-1', ['name' => $name])
->assertJson([
'code' => 1,
'message' => trans('user.closet.remove.non-existent'),
]);
$this->putJson(
route('user.closet.rename', ['tid' => -1]),
['name' => $name]
)->assertJson([
'code' => 1,
'message' => trans('user.closet.remove.non-existent'),
]);
// rename a closet item successfully
Event::fake();
$this->user->closet()->attach($texture->tid, ['item_name' => $texture->name]);
$this->postJson('/user/closet/rename/'.$texture->tid, ['name' => $name])
->assertJson([
'code' => 0,
'message' => trans('user.closet.rename.success', ['name' => $name]),
]);
$this->putJson(
route('user.closet.rename', ['tid' => $texture->tid]),
['name' => $name]
)->assertJson([
'code' => 0,
'message' => trans('user.closet.rename.success', ['name' => $name]),
]);
$this->assertEquals(1, $this->user->closet()->where('item_name', $name)->count());
Event::assertDispatched(
'closet.renaming',
@ -321,7 +329,7 @@ class ClosetControllerTest extends TestCase
$likes = $texture->likes;
// rename a not-existed texture
$this->postJson('/user/closet/remove/-1')
$this->deleteJson(route('user.closet.remove', ['tid' => -1]))
->assertJson([
'code' => 1,
'message' => trans('user.closet.remove.non-existent'),
@ -341,7 +349,7 @@ class ClosetControllerTest extends TestCase
return new Rejection('rejected');
});
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$this->postJson('/user/closet/remove/'.$texture->tid)
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
->assertJson(['code' => 1, 'message' => 'rejected']);
$this->user->closet()->detach($texture->tid);
Fakes\Filter::fake();
@ -351,7 +359,7 @@ class ClosetControllerTest extends TestCase
option(['score_award_per_like' => 5]);
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $this->user->score;
$this->postJson('/user/closet/remove/'.$texture->tid)
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
->assertJson([
'code' => 0,
'message' => trans('user.closet.remove.success'),
@ -384,7 +392,8 @@ class ClosetControllerTest extends TestCase
option(['return_score' => false]);
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $this->user->score;
$this->postJson('/user/closet/remove/'.$texture->tid)->assertJson(['code' => 0]);
$this->deleteJson(route('user.closet.remove', ['tid' => $texture->tid]))
->assertJson(['code' => 0]);
$this->assertEquals($likes - 1, Texture::find($texture->tid)->likes);
$this->assertEquals($score, $this->user->score);
$this->assertEquals(0, $this->user->closet()->count());