Skip to content

Commit 0139d04

Browse files
committed
Address review feedback on XM Directory migration
- Document the changed mailing-list column names in NEWS - Fix fetch_mailinglist roxygen param/example to use mailingListId - Warn when multiple XM Directories exist and document QUALTRICS_DIRECTORY_ID in the user-facing functions - Add tests covering directory discovery, the no-directory abort, and the multiple-directory warning
1 parent f32c511 commit 0139d04

8 files changed

Lines changed: 144 additions & 8 deletions

File tree

NEWS.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,19 @@
33
- Migrated `all_mailinglists()` and `fetch_mailinglist()` from the deprecated
44
Research Core Contacts API endpoints to the XM Directory API endpoints, ahead
55
of Qualtrics retiring the old endpoints on June 30, 2026 (#386). The directory
6-
ID is now discovered automatically from the API, so existing code requires no
7-
changes.
6+
ID is discovered automatically from the API (or can be set with the
7+
`QUALTRICS_DIRECTORY_ID` environment variable), so no change to your code is
8+
needed to keep these functions working.
9+
10+
Note that the XM Directory endpoints return a **different data shape**, so code
11+
that referenced the old column names will need to be updated:
12+
13+
- `all_mailinglists()`: the `id` column is now `mailingListId`; the
14+
`libraryId`, `category`, and `folder` columns are no longer returned; and
15+
`contactCount`, `ownerId`, and creation/modification date columns are now
16+
included.
17+
- `fetch_mailinglist()`: the `id` column is now `contactId`, and
18+
`externalDataReference` is now `extRef`.
819

920
# qualtRics 3.2.2
1021

R/all_mailinglists.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
#' Retrieve a data frame of all mailing lists from Qualtrics
22
#'
3+
#' @details
4+
#' This function uses the Qualtrics XM Directory API. The directory it queries
5+
#' is discovered automatically from your account. If your account has more than
6+
#' one XM Directory, set the `QUALTRICS_DIRECTORY_ID` environment variable to
7+
#' the directory ID you want to use; otherwise the first directory returned by
8+
#' the API is used (with a warning).
9+
#'
310
#' @template retry-advice
411
#' @importFrom purrr map_df
512
#' @importFrom purrr flatten

R/fetch_mailinglist.R

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22
#' Download a mailing list from Qualtrics
33
#'
44
#' @param mailinglistID String. Unique ID for the mailing list you want to
5-
#' download. Returned as `id` by the [all_mailinglists][qualtRics::all_mailinglists]
6-
#' function.
5+
#' download. Returned as `mailingListId` by the
6+
#' [all_mailinglists][qualtRics::all_mailinglists] function.
7+
#'
8+
#' @details
9+
#' This function uses the Qualtrics XM Directory API. The directory it queries
10+
#' is discovered automatically from your account. If your account has more than
11+
#' one XM Directory, set the `QUALTRICS_DIRECTORY_ID` environment variable to
12+
#' the directory ID you want to use; otherwise the first directory returned by
13+
#' the API is used (with a warning).
714
#'
815
#' @template retry-advice
916
#' @importFrom dplyr bind_rows
@@ -30,7 +37,7 @@
3037
#' mailinglists <- all_mailinglists()
3138
#'
3239
#' # Retrieve a single mailing list
33-
#' mailinglist <- fetch_mailinglist(mailinglists$id[1])
40+
#' mailinglist <- fetch_mailinglist(mailinglists$mailingListId[1])
3441
#' }
3542
#'
3643

R/utils.R

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ fetch_directory_id <- function() {
183183
rlang::abort("No XM Directories found for this Qualtrics account.")
184184
}
185185
dir_id <- dirs[[1]]$directoryId
186+
if (length(dirs) > 1) {
187+
rlang::warn(
188+
c(
189+
glue::glue(
190+
"This Qualtrics account has {length(dirs)} XM Directories; ",
191+
"using the first one (\"{dir_id}\")."
192+
),
193+
i = paste0(
194+
"Set the QUALTRICS_DIRECTORY_ID environment variable to choose a ",
195+
"specific directory."
196+
)
197+
)
198+
)
199+
}
186200
Sys.setenv(QUALTRICS_DIRECTORY_ID = dir_id)
187201
dir_id
188202
}

man/all_mailinglists.Rd

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

man/fetch_directory_id.Rd

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

man/fetch_mailinglist.Rd

Lines changed: 9 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
skip_on_cran()
2+
3+
test_that("fetch_directory_id discovers the directory ID from the API when unset", {
4+
withr::local_envvar(list(
5+
"QUALTRICS_API_KEY" = "abcdef",
6+
"QUALTRICS_BASE_URL" = "t.qualtrics.com",
7+
"QUALTRICS_DIRECTORY_ID" = ""
8+
))
9+
local_mocked_bindings(
10+
qualtrics_api_request = function(...) {
11+
list(result = list(elements = list(
12+
list(directoryId = "POOL_discovered123")
13+
)))
14+
}
15+
)
16+
17+
expect_identical(fetch_directory_id(), "POOL_discovered123")
18+
# Discovered ID is cached in the environment variable for the session:
19+
expect_identical(Sys.getenv("QUALTRICS_DIRECTORY_ID"), "POOL_discovered123")
20+
})
21+
22+
test_that("fetch_directory_id uses the cached env var without calling the API", {
23+
withr::local_envvar(list(
24+
"QUALTRICS_API_KEY" = "abcdef",
25+
"QUALTRICS_BASE_URL" = "t.qualtrics.com",
26+
"QUALTRICS_DIRECTORY_ID" = "POOL_cached123"
27+
))
28+
local_mocked_bindings(
29+
qualtrics_api_request = function(...) {
30+
stop("qualtrics_api_request should not be called when the ID is cached")
31+
}
32+
)
33+
34+
expect_identical(fetch_directory_id(), "POOL_cached123")
35+
})
36+
37+
test_that("fetch_directory_id aborts when no directories are found", {
38+
withr::local_envvar(list(
39+
"QUALTRICS_API_KEY" = "abcdef",
40+
"QUALTRICS_BASE_URL" = "t.qualtrics.com",
41+
"QUALTRICS_DIRECTORY_ID" = ""
42+
))
43+
local_mocked_bindings(
44+
qualtrics_api_request = function(...) {
45+
list(result = list(elements = list()))
46+
}
47+
)
48+
49+
expect_error(fetch_directory_id(), "No XM Directories found")
50+
})
51+
52+
test_that("fetch_directory_id warns and uses the first when multiple directories exist", {
53+
withr::local_envvar(list(
54+
"QUALTRICS_API_KEY" = "abcdef",
55+
"QUALTRICS_BASE_URL" = "t.qualtrics.com",
56+
"QUALTRICS_DIRECTORY_ID" = ""
57+
))
58+
local_mocked_bindings(
59+
qualtrics_api_request = function(...) {
60+
list(result = list(elements = list(
61+
list(directoryId = "POOL_first123"),
62+
list(directoryId = "POOL_second456")
63+
)))
64+
}
65+
)
66+
67+
expect_warning(
68+
dir_id <- fetch_directory_id(),
69+
"QUALTRICS_DIRECTORY_ID"
70+
)
71+
expect_identical(dir_id, "POOL_first123")
72+
})

0 commit comments

Comments
 (0)