Skip to content

Commit ade904a

Browse files
committed
ADTを特別扱いして、problemsに入れないようにする
1 parent b57d591 commit ade904a

2 files changed

Lines changed: 109 additions & 13 deletions

File tree

atcoder-problems-backend/src/crawler_utils.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,25 @@ async fn upsert_problems(
253253
name: Set(problem.name.clone()),
254254
title: Set(title),
255255
};
256-
sql_entities::problems::Entity::insert(model)
257-
.on_conflict(
258-
OnConflict::column(sql_entities::problems::Column::Id)
259-
.update_columns([
260-
sql_entities::problems::Column::ContestId,
261-
sql_entities::problems::Column::ProblemIndex,
262-
sql_entities::problems::Column::Name,
263-
sql_entities::problems::Column::Title,
264-
])
265-
.to_owned(),
266-
)
267-
.exec(db)
268-
.await?;
256+
257+
// ADTの問題は全てABCで既出であり、これらは同一視したい。
258+
// そのまま通すと問題情報がABCからADTに上書きされてしまうので、ADTの問題はproblemsには入れないようにする。
259+
// (ただしcontest_problemには入れる)
260+
if !problem.contest_id.starts_with("adt") {
261+
sql_entities::problems::Entity::insert(model)
262+
.on_conflict(
263+
OnConflict::column(sql_entities::problems::Column::Id)
264+
.update_columns([
265+
sql_entities::problems::Column::ContestId,
266+
sql_entities::problems::Column::ProblemIndex,
267+
sql_entities::problems::Column::Name,
268+
sql_entities::problems::Column::Title,
269+
])
270+
.to_owned(),
271+
)
272+
.exec(db)
273+
.await?;
274+
}
269275

270276
// Insert into contest_problem table
271277
let contest_problem = sql_entities::contest_problem::ActiveModel {

atcoder-problems-backend/tests/test_crawler_utils.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,93 @@ async fn test_crawl_contests_fetches_filtered_archive_categories() {
402402
.any(|contest| contest.id == "adt_all_20260612_2")
403403
);
404404
}
405+
406+
#[tokio::test]
407+
async fn test_crawl_adt_problems() {
408+
let db = setup_db().await.unwrap();
409+
410+
// 1. ABCのコンテスト、問題がクロールされる
411+
sql_entities::contests::Entity::insert(sql_entities::contests::ActiveModel {
412+
id: Set("abc001".to_string()),
413+
start_epoch_second: Set(0),
414+
duration_second: Set(0),
415+
title: Set("AtCoder Beginner Contest 001".to_string()),
416+
rate_change: Set("?".to_string()),
417+
})
418+
.exec(&db)
419+
.await
420+
.unwrap();
421+
422+
let mut abc_fetcher = MockProblemFetcher::new();
423+
abc_fetcher
424+
.expect_fetch_problems()
425+
.withf(|contest_id| contest_id == "abc001")
426+
.times(1)
427+
.returning(|_| {
428+
Ok(vec![Problem {
429+
id: "abc001_a".to_string(),
430+
contest_id: "abc001".to_string(),
431+
problem_index: "A".to_string(),
432+
name: "Problem A".to_string(),
433+
}])
434+
});
435+
436+
atcoder_problems_backend::crawler_utils::crawl_problems(&abc_fetcher, &db)
437+
.await
438+
.unwrap();
439+
440+
// 2. 次に、ADTのコンテスト、問題がクロールされる
441+
sql_entities::contests::Entity::insert(sql_entities::contests::ActiveModel {
442+
id: Set("adt_all_20260612".to_string()),
443+
start_epoch_second: Set(0),
444+
duration_second: Set(0),
445+
title: Set("AtCoder Daily Training 2026/06/12 All".to_string()),
446+
rate_change: Set("-".to_string()),
447+
})
448+
.exec(&db)
449+
.await
450+
.unwrap();
451+
452+
let mut adt_fetcher = MockProblemFetcher::new();
453+
adt_fetcher
454+
.expect_fetch_problems()
455+
.withf(|contest_id| contest_id == "adt_all_20260612")
456+
.times(1)
457+
.returning(|_| {
458+
Ok(vec![Problem {
459+
id: "abc001_a".to_string(),
460+
contest_id: "adt_all_20260612".to_string(),
461+
problem_index: "C".to_string(),
462+
name: "Problem C".to_string(),
463+
}])
464+
});
465+
466+
atcoder_problems_backend::crawler_utils::crawl_problems(&adt_fetcher, &db)
467+
.await
468+
.unwrap();
469+
470+
// 3. abc001_aがabc001とadt_all_20260612の両方に紐づいていることを確認する
471+
let problems_after_adt = sql_entities::problems::Entity::find()
472+
.all(&db)
473+
.await
474+
.unwrap();
475+
assert_eq!(problems_after_adt.len(), 1);
476+
assert_eq!(problems_after_adt[0].id, "abc001_a");
477+
assert_eq!(problems_after_adt[0].contest_id, "abc001");
478+
479+
let contest_problems = sql_entities::contest_problem::Entity::find()
480+
.all(&db)
481+
.await
482+
.unwrap();
483+
assert_eq!(contest_problems.len(), 2);
484+
assert!(contest_problems.iter().any(|cp| cp.contest_id == "abc001"
485+
&& cp.problem_id == "abc001_a"
486+
&& cp.problem_index == "A"));
487+
assert!(
488+
contest_problems
489+
.iter()
490+
.any(|cp| cp.contest_id == "adt_all_20260612"
491+
&& cp.problem_id == "abc001_a"
492+
&& cp.problem_index == "C")
493+
);
494+
}

0 commit comments

Comments
 (0)