Skip to content

Commit 5454f20

Browse files
authored
Merge pull request #501 from vubiostat/issue-500-dag
handle DAG within importUsers
2 parents a7cb3f6 + 9d67a90 commit 5454f20

6 files changed

Lines changed: 93 additions & 26 deletions

File tree

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* `importMetaData` bug fix when given duplicate names to exit and warn user properly.
55
* `redcapUserRoleStructure` allows new `alerts`, `api_modules`, and `data_quality_resolution` attributes.
66
* `exportUsers` properly handles the columns random_setup, random_dashboard and random_perform.
7+
* `importUsers` and `exportUsers` weren't handling data_access_group assignment properly.
78

89
## DEPRECATION NOTICES
910

R/importUserDagAssignments.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ importUserDagAssignments.redcapApiConnection <- function(rcon,
7575

7676
###################################################################
7777
# Make the API Call ####
78+
rcon$flush_dag_assignment()
7879
invisible(as.character(
7980
makeApiCall(rcon, body, ...)
8081
))

R/importUsers.R

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ importUsers.redcapApiConnection <- function(rcon,
4444
if(length(extra_access) > 0L) {
4545
m <- sprintf('Form Access variables [%s] should generally not be set when consolidate = FALSE',
4646
paste(extra_access, collapse = ','))
47-
warning(m)
47+
logWarning(m)
4848
}
4949
if(length(extra_export) > 0L) {
5050
m <- sprintf('Form Export variables [%s] should generally not be set when consolidate = FALSE',
5151
paste(extra_export, collapse = ','))
52-
warning(m)
52+
logWarning(m)
5353
}
5454
}
5555

@@ -65,8 +65,24 @@ importUsers.redcapApiConnection <- function(rcon,
6565
data <- prepUserImportData(data,
6666
rcon = rcon,
6767
consolidate = consolidate)
68-
69-
68+
69+
###################################################################
70+
# Check prior user DAG if blank ####
71+
DagAsgmt <- rcon$dag_assignment()
72+
UsersWithDags <- DagAsgmt[!is.na(DagAsgmt[,'redcap_data_access_group']), 'username']
73+
if('data_access_group' %in% names(data)) {
74+
UsersNoDag <- data[is.na(data[,'data_access_group']), 'username']
75+
} else {
76+
# if no DAG column, everyone is set to blank
77+
UsersNoDag <- data[,'username']
78+
}
79+
WarnUserDag <- intersect(UsersNoDag, UsersWithDags)
80+
if(length(WarnUserDag) > 0L) {
81+
m <- sprintf('Users with previous data access group (DAG) assignments will no longer be assigned a DAG. They will now be able to view all records: [%s]',
82+
paste(WarnUserDag, collapse = ','))
83+
logWarning(m)
84+
}
85+
7086
###################################################################
7187
# Check for Users Assigned to User Role ####
7288

@@ -100,6 +116,7 @@ importUsers.redcapApiConnection <- function(rcon,
100116
###################################################################
101117
# Make the API Call ####
102118
rcon$flush_users()
119+
rcon$flush_dag_assignment()
103120
response <- makeApiCall(rcon, body, ...)
104121

105122
invisible(as.character(response))

R/prepUserImportData.R

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ prepUserImportData <- function(data,
9090
"data_export"),
9191
add = coll)
9292

93+
if('data_access_group' %in% all_fields) {
94+
checkmate::assert_subset(x = data$data_access_group,
95+
choices = c(rcon$dags()$unique_group_name, NA_character_),
96+
add = coll)
97+
}
98+
9399
checkmate::reportAssertions(coll)
94100

95101
# Prior to redcapAPI version 2.11.5, functionality surrounding form validation
@@ -114,24 +120,17 @@ prepUserImportData <- function(data,
114120

115121
# Remove fields that cannot be updated
116122

123+
# while "data_access_group_id" and "data_access_group_label" are available from exportUsers
124+
# the DAG is set with "data_access_group"
117125
fields_to_remove <- c("email", "lastname", "firstname",
118-
"data_access_group_id", "data_access_group") #?, "data_access_groups")
126+
"data_access_group_id", "data_access_group_label")
119127
data <- data[!names(data) %in% fields_to_remove]
120128

121129
# Convert values to numeric
122130

123131
for (nm in names(data)){
124132
data[[nm]] <-
125-
if (nm == 'data_access_group'){
126-
# as of version 2.11.5, DAG is in "fields_to_remove"
127-
# this chunk will never be run
128-
# in the future we may handle it, so leaving the information below
129-
130-
# don't convert DAG into numeric
131-
# it qualifies as REDCAP_USER_TABLE_ACCESS_VARIABLES
132-
# possibly convert to numeric but leave NA?
133-
data[[nm]]
134-
} else if (nm %in% REDCAP_USER_TABLE_ACCESS_VARIABLES){
133+
if (nm %in% REDCAP_USER_TABLE_ACCESS_VARIABLES){
135134
prepUserImportData_castAccessVariable(data[[nm]])
136135
} else if (nm %in% form_access_field){
137136
prepUserImportData_castFormAccess(rcon, data[[nm]])

R/redcapDataStructure.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ REDCAP_USER_TABLE_ACCESS_VARIABLES <-
365365
c("design",
366366
"alerts",
367367
"user_rights",
368-
"data_access_group",
368+
"data_access_groups",
369369
"reports",
370370
"stats_and_charts",
371371
"manage_survey_participants",

tests/testthat/test-101-userMethods-Functionality.R

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,24 @@ test_that(
1616
# Verify the user was added
1717
expect_true(EXPENDABLE_USER %in% rcon$users()$username)
1818

19+
# ensure export > import > export equality
20+
# initial import fixes the state
21+
importUsers(rcon, rcon$users())
22+
Users <- exportUsers(rcon)
23+
importUsers(rcon, Users)
24+
# cache should be correct
25+
expect_equal(rcon$users(), exportUsers(rcon))
26+
expect_equal(rcon$users(), Users)
27+
1928
# Modify the user permissions
2029

2130
n_imported <- importUsers(rcon,
2231
data = data.frame(username = EXPENDABLE_USER,
2332
alerts = 1))
2433
expect_equal(n_imported, "1")
2534

26-
Users <- exportUsers(rcon)
27-
Users <- Users[rcon$users()$username %in% EXPENDABLE_USER, ]
35+
Users <- rcon$users()
36+
Users <- Users[Users$username %in% EXPENDABLE_USER, ]
2837
expect_true(Users$alerts %in% "Access")
2938
}
3039
)
@@ -82,7 +91,7 @@ test_that(
8291
data = data.frame(username = EXPENDABLE_USER,
8392
data_export = 1,
8493
forms = c("record_id:0"),
85-
# leaving an instrument off implicitly sets permission to 0
94+
# leaving an instrument off implicitly sets permission to 0
8695
forms_export = ""),
8796
consolidate = FALSE)
8897

@@ -97,20 +106,60 @@ test_that(
97106
record_id_form_access = 1,
98107
forms = 'record_id:0',
99108
forms_export = ''),
100-
consolidate = FALSE))
109+
consolidate = FALSE))
101110
Users <- exportUsers(rcon)
102111
Users <- Users[Users$username %in% EXPENDABLE_USER, ]
103112
expect_true(grepl("record_id:0",Users$forms))
104-
105-
# NEED TO ADD TWO TESTS
106-
# Update data_access_group to "No Assignment"
107-
# functionality not supported as of version 2.11.5
108-
# Update data_access_group to a legitimate DAG
109-
# functionality not supported as of version 2.11.5
110113
}
111114
)
112115

116+
test_that(
117+
"Import User DAG Assignments",
118+
{
119+
skip_if(!RUN_USER_TESTS,
120+
"User tests without an expendable user could have negative consequences and are not run.")
121+
122+
if (EXPENDABLE_USER %in% rcon$users()$username){
123+
deleteUsers(rcon,
124+
users = EXPENDABLE_USER)
125+
}
126+
127+
importUsers(rcon,
128+
data = data.frame(username = EXPENDABLE_USER))
129+
130+
# create temporary DAG; it probably already exists at this point
131+
TmpDag <- !'test_dag_1' %in% exportDags(rcon)$unique_group_name
132+
if(TmpDag) {
133+
NewDag <- data.frame(data_access_group_name = 'test_dag_1',
134+
unique_group_name = NA_character_)
135+
importDags(rcon, data = NewDag)
136+
}
113137

138+
# Update data_access_group to a legitimate DAG
139+
Users <- exportUsers(rcon)
140+
Users <- Users[Users$username %in% EXPENDABLE_USER, ]
141+
Users[,'data_access_group'] <- 'test_dag_1'
142+
importUsers(rcon, data = Users)
143+
DagAsgmt <- exportUserDagAssignments(rcon)
144+
expect_equal('test_dag_1',
145+
DagAsgmt[DagAsgmt[,'username'] == EXPENDABLE_USER, 'redcap_data_access_group'])
146+
147+
# Update data_access_group to "No Assignment"
148+
Users[,'data_access_group'] <- NA_character_
149+
# warning indicates this gives view access to all records
150+
expect_warning(importUsers(rcon, data = Users), 'view all records')
151+
DagAsgmt <- exportUserDagAssignments(rcon)
152+
expect_true(is.na(DagAsgmt[DagAsgmt[,'username'] == EXPENDABLE_USER, 'redcap_data_access_group']))
153+
154+
# Try a bad DAG
155+
Users[,'data_access_group'] <- 'uncouth_dag'
156+
expect_error(importUsers(rcon, data = Users))
157+
158+
if(TmpDag) {
159+
deleteDags(rcon, 'test_dag_1')
160+
}
161+
}
162+
)
114163

115164
test_that(
116165
"Export User Options",

0 commit comments

Comments
 (0)