Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion docs/react-dev-demo-data.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- Roadmap: DEV-072 -->
<!-- Roadmap: DEV-072, DEV-083 -->

# Тестовые данные React-dev

Expand All @@ -21,6 +21,23 @@ React-dev backend.
- решение с частично заполненным draft;
- решение с submitted Evaluation и completed assignment.

### Новостная лента DEV-083

Тот же запуск создаёт отдельный публичный проект
`[DEMO] Новостная лента React-dev` под руководством первого DEMO-участника и
связанный набор для проверки React-ленты:

- 11 публичных новостей программы;
- 11 публичных новостей DEMO-проекта;
- 11 публичных новостей, распределённых между DEMO-пользователями;
- одну новость программы с аудиторией `program_participants`;
- публикации с лайками, просмотрами и комментариями, а также публикации без реакций;
- 21 хронологический комментарий у одной новости для проверки второй страницы.

Во всех трёх публичных вкладках `/feed/news/` есть вторая страница при стандартном
лимите 10. Внутренняя новость отсутствует в списке, открывается по возвращённому
командой ID у участника DEMO-программы и отвечает `404` постороннему пользователю.

## Меры безопасности

Команда завершается до любой записи, если не выполнено хотя бы одно условие:
Expand All @@ -37,6 +54,12 @@ Reset находит программу только по одновременн
это не позволяет каскадному удалению затронуть их возможные внешние связи.
Обычные пользователи и программы с похожими названиями не удаляются.

Проект DEV-083 определяется точным служебным именем и ожидаемым DEMO-руководителем.
Если это имя уже занято проектом другого руководителя, транзакция завершается без
изменений. Новости удаляются только по сочетанию ожидаемого источника и полного
точного текста; общий префикс `[DEMO]` не является признаком владения. Поэтому
`--reset` не удаляет другие новости DEMO-пользователей и проекты с похожими именами.

## Обычный запуск

В окружении изолированного React-dev backend включить setting, задать пароль и
Expand All @@ -55,6 +78,20 @@ python manage.py seed_react_dev_demo --confirm-react-dev --dry-run
```

Команда показывает план и итоговые количества, затем откатывает транзакцию.
В итог также входят количества проектов, публичных и внутренних новостей, лайков,
просмотров и комментариев, а также ID внутренней новости. Пароль не выводится.

Пример части вывода DEV-083:

```text
проекты: 1
публичные новости: 33
внутренние новости: 1
лайки: 6
просмотры: 9
комментарии: 23
ID внутренней новости: <ID в текущей базе>
```

## Reset

Expand Down
8 changes: 7 additions & 1 deletion docs/react-news-feed-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,13 @@ staff/superuser. `news_id` входит в lookup комментария, поэ
- создание публикаций из общей ленты не добавлено: программы продолжают
публиковать через context endpoint;
- UI ленты, popup, deep-link recovery и копирование ссылки входят в DEV-083.2;
- DEMO-новости, лайки и комментарии входят в DEV-083.3.
- DEMO-набор DEV-083.3 создаётся существующей защищённой командой
`python manage.py seed_react_dev_demo --confirm-react-dev`. Он содержит по 11
публичных новостей программы, проекта и пользователей, реакции и 21 комментарий
у одной публикации. Отдельная новость `program_participants` предназначена для
проверки detail-доступа участника и безопасного `404` для постороннего пользователя.
Точные правила повторного запуска, `--dry-run` и `--reset` описаны в
`docs/react-dev-demo-data.md`.

Angular-аудит подтвердил: карточка копирует отдельную ссылку, project/profile
detail открывает новость в модальном маршруте, а блок комментариев в карточке
Expand Down
9 changes: 8 additions & 1 deletion partner_programs/management/commands/seed_react_dev_demo.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Roadmap: DEV-072
# Roadmap: DEV-072, DEV-083
# Безопасная точка запуска демонстрационного набора только для React-dev.

import os
Expand Down Expand Up @@ -75,6 +75,13 @@ def handle(self, *args, **options):
"assignments": "назначения",
"evaluations": "оценки",
"scores": "баллы",
"projects": "проекты",
"public_news": "публичные новости",
"internal_news": "внутренние новости",
"likes": "лайки",
"views": "просмотры",
"comments": "комментарии",
"internal_news_id": "ID внутренней новости",
}
self.stdout.write("Результат:")
for label, count in summary.as_dict().items():
Expand Down
60 changes: 57 additions & 3 deletions partner_programs/services/react_dev_demo.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Roadmap: DEV-072
# Roadmap: DEV-072, DEV-083
# Повторяемый связанный набор данных для ручной проверки React-dev.

from dataclasses import dataclass
Expand All @@ -10,6 +10,8 @@
from django.db.models import Q
from django.utils import timezone

from core.models import Like, View
from news.models import NewsComment
from partner_programs.models import (
Application,
Evaluation,
Expand All @@ -29,6 +31,11 @@
submit_evaluation,
update_draft_evaluation,
)
from partner_programs.services.react_dev_news_demo import (
ReactDevNewsDemoDataError,
delete_react_dev_news_demo_data,
ensure_react_dev_news_demo_data,
)
from partner_programs.services.submission_assignments import (
create_submission_assignment,
)
Expand Down Expand Up @@ -153,6 +160,13 @@ class ReactDevDemoSummary:
assignments: int
evaluations: int
scores: int
projects: int
public_news: int
internal_news: int
likes: int
views: int
comments: int
internal_news_id: int

def as_dict(self):
return {
Expand All @@ -167,6 +181,13 @@ def as_dict(self):
"assignments": self.assignments,
"evaluations": self.evaluations,
"scores": self.scores,
"projects": self.projects,
"public_news": self.public_news,
"internal_news": self.internal_news,
"likes": self.likes,
"views": self.views,
"comments": self.comments,
"internal_news_id": self.internal_news_id,
}


Expand Down Expand Up @@ -529,7 +550,7 @@ def _ensure_evaluation_states(submissions, criteria, expert_user, manager):
)


def _summary(program):
def _summary(program, news_demo):
application_qs = Application.objects.filter(program=program)
submission_qs = Submission.objects.filter(program=program)
evaluation_qs = Evaluation.objects.filter(submission__program=program)
Expand All @@ -556,6 +577,21 @@ def _summary(program):
scores=EvaluationScore.objects.filter(
evaluation__submission__program=program
).count(),
projects=1,
public_news=news_demo.public_news_count,
internal_news=1,
likes=Like.objects.filter(
content_type__app_label="news",
content_type__model="news",
object_id__in=news_demo.all_news_ids,
).count(),
views=View.objects.filter(
content_type__app_label="news",
content_type__model="news",
object_id__in=news_demo.all_news_ids,
).count(),
comments=NewsComment.objects.filter(news_id__in=news_demo.all_news_ids).count(),
internal_news_id=news_demo.internal_news.pk,
)


Expand All @@ -564,6 +600,17 @@ def build_react_dev_demo_data(*, password, reset=False, dry_run=False):

with transaction.atomic():
if reset:
existing_users = {
spec["key"]: User.objects.filter(email=spec["email"]).first()
for spec in DEMO_USER_SPECS
}
try:
delete_react_dev_news_demo_data(
program=_find_owned_program(),
users_by_key=existing_users,
)
except ReactDevNewsDemoDataError as exc:
raise ReactDevDemoDataError(str(exc)) from exc
_delete_owned_program()

users = {spec["key"]: _ensure_user(spec, password) for spec in DEMO_USER_SPECS}
Expand All @@ -584,7 +631,14 @@ def build_react_dev_demo_data(*, password, reset=False, dry_run=False):
users["expert"],
users["manager"],
)
summary = _summary(program)
try:
news_demo = ensure_react_dev_news_demo_data(
program=program,
users_by_key=users,
)
except ReactDevNewsDemoDataError as exc:
raise ReactDevDemoDataError(str(exc)) from exc
summary = _summary(program, news_demo)

if dry_run:
transaction.set_rollback(True)
Expand Down
Loading
Loading