- 소유권 게이팅(common/authz): 변경 액션 본인∪OWNER, 협력사 삭제 OWNER 전용 - 견적 수동 낙찰(award) + 작성자명(creatorName) 표시 + 전화번호 입력 컴포넌트 + 카드 엑셀 업로드 - supplier_type 은 이번 커밋 미변경(다음 커밋에서 코드부터 정리 예정) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
3.0 KiB
Python
66 lines
3.0 KiB
Python
"""card 도메인 스코프 e2e — 개인 카드는 소유자만, 전체(공용) 카드는 누구나.
|
|
스코프 규칙: user_id 있으면 개인(본인만 조회·관리) / NULL 이면 전체(모든 유저 조회·수정·삭제). 로그인은 auth_headers."""
|
|
|
|
|
|
async def _create_card(client, headers, *, number, name="카드", is_shared=False, is_wildcard=False):
|
|
r = await client.post(
|
|
"/v1/card/create",
|
|
json={
|
|
"is_wildcard": is_wildcard,
|
|
"is_shared": is_shared,
|
|
"name": name,
|
|
"number": number,
|
|
"script": "안녕하세요",
|
|
},
|
|
headers=headers,
|
|
)
|
|
body = r.json()
|
|
assert body["result"]["success"] is True, body
|
|
return body["card"]["nego_card_id"]
|
|
|
|
|
|
async def _list_numbers(client, headers):
|
|
r = await client.get("/v1/card/list", headers=headers)
|
|
return {c["number"] for c in r.json().get("cards", [])}
|
|
|
|
|
|
async def test_personal_card_is_owner_only(client, auth_headers):
|
|
"""검증: user_id 가 박힌 개인 카드는 소유자 목록·단건조회에만 노출되고 타 유저에겐 숨는다.
|
|
기대결과: A 목록엔 있고 B 목록엔 없음, B 의 단건 조회는 success=False(CARD_NOT_FOUND)."""
|
|
ha = await auth_headers("cardA")
|
|
hb = await auth_headers("cardB")
|
|
cid = await _create_card(client, ha, number="P-1", is_shared=False)
|
|
|
|
assert "P-1" in await _list_numbers(client, ha)
|
|
assert "P-1" not in await _list_numbers(client, hb)
|
|
assert (await client.get(f"/v1/card/{cid}", headers=hb)).json()["result"]["success"] is False
|
|
|
|
|
|
async def test_shared_card_visible_to_all(client, auth_headers):
|
|
"""검증: is_shared=True 카드는 user_id NULL 로 저장돼 모든 유저 목록·단건조회에 노출된다.
|
|
기대결과: A·B 목록 모두에 존재, 비생성자 B 의 단건 조회 success=True, is_shared 플래그 True."""
|
|
ha = await auth_headers("cardSA")
|
|
hb = await auth_headers("cardSB")
|
|
cid = await _create_card(client, ha, number="S-1", is_shared=True)
|
|
|
|
assert "S-1" in await _list_numbers(client, ha)
|
|
assert "S-1" in await _list_numbers(client, hb)
|
|
got = await client.get(f"/v1/card/{cid}", headers=hb)
|
|
assert got.json()["result"]["success"] is True
|
|
assert got.json()["card"]["is_shared"] is True
|
|
|
|
|
|
async def test_shared_card_editable_and_deletable_by_anyone(client, auth_headers):
|
|
"""검증: 전체(공용) 카드는 소유자가 없어 아무 유저나 수정·삭제 가능(정책: 누구나).
|
|
기대결과: 비생성자 B 의 수정·삭제 모두 success=True, 삭제 후 목록에서 사라짐."""
|
|
ha = await auth_headers("cardEA")
|
|
hb = await auth_headers("cardEB")
|
|
cid = await _create_card(client, ha, number="S-EDIT", is_shared=True)
|
|
|
|
upd = await client.patch(f"/v1/card/update/{cid}", json={"name": "B가 수정"}, headers=hb)
|
|
assert upd.json()["result"]["success"] is True
|
|
|
|
dele = await client.delete(f"/v1/card/delete/{cid}", headers=hb)
|
|
assert dele.json()["result"]["success"] is True
|
|
assert "S-EDIT" not in await _list_numbers(client, hb)
|