fix duplication of private textures (fix #194)
This commit is contained in:
parent
8f2e48df52
commit
b5a1f2ffc2
|
|
@ -249,16 +249,21 @@ class SkinlibController extends Controller
|
|||
$hash = hash_file('sha256', $file);
|
||||
$hash = $filter->apply('uploaded_texture_hash', $hash, [$file]);
|
||||
|
||||
$duplicated = Texture::where('hash', $hash)->where('public', true)->first();
|
||||
/** @var User */
|
||||
$user = Auth::user();
|
||||
|
||||
$duplicated = Texture::where('hash', $hash)
|
||||
->where(function ($query) use ($user) {
|
||||
return $query->where('public', true)
|
||||
->orWhere('uploader', $user->uid);
|
||||
})
|
||||
->first();
|
||||
if ($duplicated) {
|
||||
// if the texture already uploaded was set to private,
|
||||
// then allow to re-upload it.
|
||||
return json(trans('skinlib.upload.repeated'), 2, ['tid' => $duplicated->tid]);
|
||||
}
|
||||
|
||||
/** @var User */
|
||||
$user = Auth::user();
|
||||
|
||||
$size = ceil($file->getSize() / 1024);
|
||||
$isPublic = is_string($data['public'])
|
||||
? $data['public'] === '1'
|
||||
|
|
@ -342,6 +347,15 @@ class SkinlibController extends Controller
|
|||
return json(trans('skinlib.upload.lack-score'), 1);
|
||||
}
|
||||
|
||||
if (!$texture->public) {
|
||||
$duplicated = Texture::where('hash', $texture->hash)
|
||||
->where('public', true)
|
||||
->first();
|
||||
if ($duplicated) {
|
||||
return json(trans('skinlib.upload.repeated'), 2, ['tid' => $duplicated->tid]);
|
||||
}
|
||||
}
|
||||
|
||||
$dispatcher->dispatch('texture.privacy.updating', [$texture]);
|
||||
|
||||
$uploader->score += $score_diff;
|
||||
|
|
|
|||
|
|
@ -191,12 +191,29 @@ const Show: React.FC = () => {
|
|||
return
|
||||
}
|
||||
|
||||
const { code, message } = await fetch.put<fetch.ResponseBody>(
|
||||
type Ok = { code: 0; message: string }
|
||||
type Err = { code: 1; message: string }
|
||||
type Duplicated = { code: 2; message: string; data: { tid: number } }
|
||||
|
||||
const resp = await fetch.put<Ok | Err | Duplicated>(
|
||||
urls.texture.privacy(texture.tid),
|
||||
)
|
||||
const { code, message } = resp
|
||||
if (code === 0) {
|
||||
toast.success(message)
|
||||
setTexture((texture) => ({ ...texture, public: !texture.public }))
|
||||
} else if (resp.code === 2) {
|
||||
try {
|
||||
await showModal({
|
||||
mode: 'confirm',
|
||||
text: message,
|
||||
okButtonText: t('user.viewInSkinlib'),
|
||||
})
|
||||
window.location.href =
|
||||
blessing.base_url + urls.skinlib.show(resp.data.tid)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
} else {
|
||||
toast.error(message)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -575,6 +575,48 @@ describe('change privacy', () => {
|
|||
expect(getByRole('alert')).toHaveClass('alert-danger')
|
||||
expect(queryByText(t('skinlib.setAsPublic'))).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('duplicated texture with confirmed', async () => {
|
||||
fetch.get.mockResolvedValue({ ...fixtureSkin, public: false })
|
||||
fetch.put.mockResolvedValue({
|
||||
code: 2,
|
||||
message: 'duplicated',
|
||||
data: { tid: 2 },
|
||||
})
|
||||
|
||||
const { getByText, queryByText } = render(<Show />)
|
||||
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
|
||||
|
||||
fireEvent.click(getByText(t('skinlib.setAsPublic')))
|
||||
fireEvent.click(getByText(t('general.confirm')))
|
||||
await waitFor(() =>
|
||||
expect(fetch.put).toBeCalledWith(urls.texture.privacy(fixtureSkin.tid)),
|
||||
)
|
||||
expect(queryByText('duplicated')).toBeInTheDocument()
|
||||
expect(queryByText(t('skinlib.setAsPublic'))).toBeInTheDocument()
|
||||
fireEvent.click(getByText(t('user.viewInSkinlib')))
|
||||
})
|
||||
|
||||
it('duplicated texture with cancelled', async () => {
|
||||
fetch.get.mockResolvedValue({ ...fixtureSkin, public: false })
|
||||
fetch.put.mockResolvedValue({
|
||||
code: 2,
|
||||
message: 'duplicated',
|
||||
data: { tid: 2 },
|
||||
})
|
||||
|
||||
const { getByText, queryByText } = render(<Show />)
|
||||
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
|
||||
|
||||
fireEvent.click(getByText(t('skinlib.setAsPublic')))
|
||||
fireEvent.click(getByText(t('general.confirm')))
|
||||
await waitFor(() =>
|
||||
expect(fetch.put).toBeCalledWith(urls.texture.privacy(fixtureSkin.tid)),
|
||||
)
|
||||
expect(queryByText('duplicated')).toBeInTheDocument()
|
||||
expect(queryByText(t('skinlib.setAsPublic'))).toBeInTheDocument()
|
||||
fireEvent.click(getByText(t('general.cancel')))
|
||||
})
|
||||
})
|
||||
|
||||
describe('delete texture', () => {
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@
|
|||
## Fixed
|
||||
|
||||
- Fixed duplicated route names.
|
||||
- Fixed duplication of private textures.
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@
|
|||
## 修复
|
||||
|
||||
- 修复重复的路由命名
|
||||
- 修复私有材质的重复问题
|
||||
|
|
|
|||
|
|
@ -449,6 +449,20 @@ class SkinlibControllerTest extends TestCase
|
|||
'data' => ['tid' => $texture->tid],
|
||||
]);
|
||||
|
||||
// upload a duplicated private texture
|
||||
$texture->uploader = $user->uid;
|
||||
$texture->save();
|
||||
$this->postJson(route('texture.upload'), [
|
||||
'name' => 'texture',
|
||||
'public' => true,
|
||||
'type' => 'steve',
|
||||
'file' => $upload,
|
||||
])->assertJson([
|
||||
'code' => 2,
|
||||
'message' => trans('skinlib.upload.repeated'),
|
||||
'data' => ['tid' => $texture->tid],
|
||||
]);
|
||||
|
||||
// rejected
|
||||
$filter->add('can_upload_texture', function ($can, $file, $name) {
|
||||
$this->assertInstanceOf(UploadedFile::class, $file);
|
||||
|
|
@ -589,6 +603,19 @@ class SkinlibControllerTest extends TestCase
|
|||
}
|
||||
);
|
||||
|
||||
// duplicated
|
||||
$duplicated = $texture->replicate();
|
||||
$duplicated->uploader = $other->uid;
|
||||
$duplicated->public = true;
|
||||
$duplicated->save();
|
||||
$texture->public = false;
|
||||
$texture->save();
|
||||
$uploader->score = (int) option('private_score_per_storage');
|
||||
$uploader->save();
|
||||
$this->putJson(route('texture.privacy', ['texture' => $texture]))
|
||||
->assertJson(['code' => 2, 'message' => trans('skinlib.upload.repeated')]);
|
||||
$duplicated->delete();
|
||||
|
||||
$this->putJson(route('texture.privacy', ['texture' => $texture]))
|
||||
->assertJson([
|
||||
'code' => 0,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user