Skip to content

Commit 6acc04e

Browse files
committed
Added unit tests
1 parent 67eddfb commit 6acc04e

File tree

10 files changed

+192
-58
lines changed

10 files changed

+192
-58
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: wbdataset
22
Title: Making Datasets Truly Interoperable and Reusable in R with Wikibase
3-
Version: 0.1.1042
4-
Date: 2024-04-07
3+
Version: 0.1.1043
4+
Date: 2024-04-10
55
Authors@R:
66
c(person(given="Daniel", family="Antal",
77
email= "[email protected]",

R/check_existing_item.R

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
1-
#' @title Check if a label already has an item.
2-
#' @description Avoid failed writing attempts by checking if a label already
3-
#' matches an item.
4-
#' @details A wrapper around
1+
#' @title Check for Existing Items in Wikibase
2+
#'
3+
#' @description This function searches for existing items in a specified
4+
#' Wikibase instance that match a given label in a specified language. It helps
5+
#' prevent duplicate item creation by identifying existing matches.
6+
#'
7+
#' @details The function interfaces with the Wikibase API's `wbsearchentities`
8+
#' action to perform a search based on the provided label (`search_term`) and
9+
#' language. It returns information about matching items, facilitating the
10+
#' management of data consistency within the Wikibase. See:
511
#' \href{https://www.wikidata.org/w/api.php?action=help&modules=wbsearchentities}{MediaWiki
612
#' action=wbsearchentities}.
7-
#' @param action Defaults to \code{"create_item"}.
8-
#' @param search_term A label in the given language, for example, "Estonia".
9-
#' @param language A single language code that indicates the language of the
10-
#' label and description, using BCP 47-compliant language tags (e.g., "en" for
11-
#' English, "fr" for French). Defaults to \code{"en"} for English.
12-
#' @param wikibase_api_url The full URL of the Wikibase API, which is the
13-
#' address that the \code{wbdataset} R client sends requests to when
14-
#' interacting with the knowledge base. In this case it defaults to
15-
#' \code{'https://www.wikidata.org/w/api.php'}, Wikidata itself, where no
16-
#' CSRF is needed.
17-
#' @param csrf The CSRF token of your session, received with
18-
#' \code{\link{get_csrf}}, not needed if
19-
#' \code{wikibase_api_url="https://www.wikidata.org/w/api.php"}. Defaults
20-
#' to \code{NULL}.
13+
#'
14+
#' @param search_term A character string representing the label to search for in
15+
#' the Wikibase. For example, `"Estonian National Museum"`.
16+
#' @param language A character string specifying the language code of the label,
17+
#' adhering to BCP 47 standards (e.g., `"en"` for English). Defaults to
18+
#' `"en"`.
19+
#' @param action A character string indicating the action being performed.
20+
#' Defaults to `"create_item"`.
21+
#' @param log_file_name A character string specifying the name of the log file.
22+
#' Defaults to `NA_character_`.
23+
#' @param data_curator An object of class `person` representing the data
24+
#' curator. Defaults to `person("Unknown", "Person")`.
25+
#' @return A `dataset_df` object containing information about the matching
26+
#' item(s), including action performed, item ID, label, description, language,
27+
#' and other metadata. Returns `NULL` if no matching items are found.
2128
#' @inheritParams create_item
2229
#' @return A data.frame or NULL.
2330
#' @examples
@@ -44,8 +51,17 @@ check_existing_item <- function(search_term,
4451
action_timestamp <- action_timestamp_create()
4552
action_time <- Sys.time()
4653

47-
if ( length(search_term)!=1) {
48-
stop("check_existing_item(search_term, ...): length of search term must be 1.")
54+
55+
if (!is.character(search_term) || length(search_term) != 1 || nchar(search_term) == 0) {
56+
stop("Invalid input in check_existing_item(): 'search_term' must be a non-empty character string.")
57+
}
58+
59+
if (!is.character(language) || length(language) != 1 || nchar(language) == 0) {
60+
stop("Invalid input in check_existing_item(): 'language' must be a non-empty character string.")
61+
}
62+
63+
if (!is.character(wikibase_api_url) || length(wikibase_api_url) != 1 || !grepl("^https?://", wikibase_api_url)) {
64+
stop("Invalid input in check_existing_item(): 'wikibase_api_url' must be a valid URL string.")
4965
}
5066

5167
get_search <- httr::POST(

R/check_existing_property.R

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,19 @@ check_existing_property <- function(
4646
action_timestamp <- action_timestamp_create()
4747
action_time <- Sys.time()
4848

49-
if ( length(search_term)!=1) {
50-
stop("check_existing_item(search_term, ...): length of search term must be 1.")
49+
if (!is.character(search_term) || length(search_term) != 1 || nchar(search_term) == 0) {
50+
stop("Invalid input in check_existing_property(): 'search_term' must be a non-empty character string.")
5151
}
5252

53+
if (!is.character(language) || length(language) != 1 || nchar(language) == 0) {
54+
stop("Invalid input in check_existing_property(): 'language' must be a non-empty character string.")
55+
}
56+
57+
if (!is.character(wikibase_api_url) || length(wikibase_api_url) != 1 || !grepl("^https?://", wikibase_api_url)) {
58+
stop("Invalid input in check_existing_property(): 'wikibase_api_url' must be a valid URL string.")
59+
}
60+
61+
5362
get_search <- httr::POST(
5463
wikibase_api_url,
5564
body = list(

R/get_claim.R

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ get_claim <- function(qid = "Q528626",
5454
wikibase_api_url = "https://www.wikidata.org/w/api.php",
5555
csrf = NULL,
5656
first = TRUE) {
57+
58+
if (!is_qid(qid)) {
59+
stop(sprintf("Invalid QID: '%s'. QIDs must begin with 'Q' followed by digits (e.g., 'Q42').", qid))
60+
}
61+
62+
if (!is_pid(property)) {
63+
stop(sprintf("Invalid property ID: '%s'. Properties must begin with 'P' followed by digits (e.g., 'P31').", property))
64+
}
65+
5766
response <- httr::POST(
5867
wikibase_api_url,
5968
body = list(

man/check_existing_item.Rd

Lines changed: 27 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/is_pid.Rd

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/is_qid.Rd

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-check_existing_item.R

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,46 @@ test_that("check_existing_item() works", {
33
search_term = "Estonian National Museum",
44
language = "en"
55
)
6+
expect_true(inherits(test, "data.frame"))
67
expect_equal(
78
as.character(test$rowid),
89
"wbi:Q1370397"
910
)
1011
})
12+
13+
test_that("check_existing_item() handles invalid inputs appropriately", {
14+
# Test for non-character search_term
15+
expect_error(
16+
check_existing_item(search_term = 123, language = "en"),
17+
"Invalid input in check_existing_item(): 'search_term' must be a non-empty character string.",
18+
fixed = TRUE
19+
)
20+
21+
# Test for empty search_term
22+
expect_error(
23+
check_existing_item(search_term = "", language = "en"),
24+
"Invalid input in check_existing_item(): 'search_term' must be a non-empty character string.",
25+
fixed = TRUE
26+
)
27+
28+
# Test for non-character language
29+
expect_error(
30+
check_existing_item(search_term = "Estonian National Museum", language = 123),
31+
"Invalid input in check_existing_item(): 'language' must be a non-empty character string.",
32+
fixed = TRUE
33+
)
34+
35+
# Test for empty language
36+
expect_error(
37+
check_existing_item(search_term = "Estonian National Museum", language = ""),
38+
"Invalid input in check_existing_item(): 'language' must be a non-empty character string.",
39+
fixed = TRUE
40+
)
41+
42+
# Test for invalid wikibase_api_url
43+
expect_error(
44+
check_existing_item(search_term = "Estonian National Museum", language = "en", wikibase_api_url = "invalid_url"),
45+
"Invalid input in check_existing_item(): 'wikibase_api_url' must be a valid URL string.",
46+
fixed = TRUE
47+
)
48+
})

tests/testthat/test-check_existing_property.R

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,41 @@ test_that("check_existing_property() works", {
99
"wikibase-item"
1010
)
1111
})
12+
13+
14+
test_that("check_existing_property() handles invalid inputs appropriately", {
15+
# Test for non-character search_term
16+
expect_error(
17+
check_existing_property(search_term = 123, language = "en"),
18+
"Invalid input in check_existing_property(): 'search_term' must be a non-empty character string.",
19+
fixed = TRUE
20+
)
21+
22+
# Test for empty search_term
23+
expect_error(
24+
check_existing_property(search_term = "", language = "en"),
25+
"Invalid input in check_existing_property(): 'search_term' must be a non-empty character string.",
26+
fixed = TRUE
27+
)
28+
29+
# Test for non-character language
30+
expect_error(
31+
check_existing_property(search_term = "Estonian National Museum", language = 123),
32+
"Invalid input in check_existing_property(): 'language' must be a non-empty character string.",
33+
fixed = TRUE
34+
)
35+
36+
# Test for empty language
37+
expect_error(
38+
check_existing_property(search_term = "Estonian National Museum", language = ""),
39+
"Invalid input in check_existing_property(): 'language' must be a non-empty character string.",
40+
fixed = TRUE
41+
)
42+
43+
# Test for invalid wikibase_api_url
44+
expect_error(
45+
check_existing_property(search_term = "Estonian National Museum", language = "en", wikibase_api_url = "invalid_url"),
46+
"Invalid input in check_existing_property(): 'wikibase_api_url' must be a valid URL string.",
47+
fixed = TRUE
48+
)
49+
})
Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ test_that("get_claim() throws error for missing property", {
55
)
66
})
77

8+
test_that("get_claim() throws an error for invalid QID", {
9+
expect_error(
10+
get_claim(qid = "invalidQID", property = "P31"),
11+
"Invalid QID: 'invalidQID'. QIDs must begin with 'Q' followed by digits (e.g., 'Q42').",
12+
fixed = TRUE
13+
)
14+
})
15+
16+
test_that("get_claim() throws an error for invalid property ID", {
17+
expect_error(
18+
get_claim(qid = "Q42", property = "invalidPID"),
19+
"Invalid property ID: 'invalidPID'. Properties must begin with 'P' followed by digits (e.g., 'P31').",
20+
fixed = TRUE
21+
)
22+
})
23+
24+
825
test_that("get_claim(): wikibase-item value correctly returned", {
926
expect_equal(
1027
get_claim(qid = "Q28104185", property = "P1889")$P1889,
@@ -36,10 +53,10 @@ test_that("get_claim(): time value correctly returned", {
3653
wikibase_api_url = "https://www.wikidata.org/w/api.php")$P1889,
3754
"Q234138")
3855
expect_equal(
39-
get_claim(qid = "Q28104185",
40-
property = "P1889",
41-
wikibase_api_url = "https://www.wikidata.org/w/api.php")$type,
42-
"wikibase-item")
56+
get_claim(qid = "Q28104185",
57+
property = "P1889",
58+
wikibase_api_url = "https://www.wikidata.org/w/api.php")$type,
59+
"wikibase-item")
4360
})
4461

4562
test_that("get_claim(): external-id value correctly returned", {

0 commit comments

Comments
 (0)