diff --git a/src/main/resources/org/broadinstitute/dsde/sam/liquibase/changelog.xml b/src/main/resources/org/broadinstitute/dsde/sam/liquibase/changelog.xml index 69e13dd4f..6239c4543 100644 --- a/src/main/resources/org/broadinstitute/dsde/sam/liquibase/changelog.xml +++ b/src/main/resources/org/broadinstitute/dsde/sam/liquibase/changelog.xml @@ -31,7 +31,6 @@ - diff --git a/src/main/resources/org/broadinstitute/dsde/sam/liquibase/changesets/20240806_add_profile_info_table.xml b/src/main/resources/org/broadinstitute/dsde/sam/liquibase/changesets/20240806_add_profile_info_table.xml deleted file mode 100644 index d539a429e..000000000 --- a/src/main/resources/org/broadinstitute/dsde/sam/liquibase/changesets/20240806_add_profile_info_table.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala index ed371eb96..8018692e9 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala @@ -1355,57 +1355,11 @@ class PostgresDirectoryDAO(protected val writeDbRef: DbReference, protected val val userAttributesTable = UserAttributesTable.syntax val userAttributesColumns = UserAttributesTable.column samsql""" - insert into ${UserAttributesTable as userAttributesTable} ( - ${userAttributesColumns.samUserId}, - ${userAttributesColumns.marketingConsent}, - ${userAttributesColumns.firstName}, - ${userAttributesColumns.lastName}, - ${userAttributesColumns.organization}, - ${userAttributesColumns.contactEmail}, - ${userAttributesColumns.title}, - ${userAttributesColumns.department}, - ${userAttributesColumns.interestInTerra}, - ${userAttributesColumns.programLocationCity}, - ${userAttributesColumns.programLocationState}, - ${userAttributesColumns.programLocationCountry}, - ${userAttributesColumns.researchArea}, - ${userAttributesColumns.additionalAttributes}, - ${userAttributesColumns.createdAt}, - ${userAttributesColumns.updatedAt} - ) values ( - ${userAttributes.userId}, - ${userAttributes.marketingConsent}, - ${userAttributes.firstName}, - ${userAttributes.lastName}, - ${userAttributes.organization}, - ${userAttributes.contactEmail}, - ${userAttributes.title}, - ${userAttributes.department}, - ARRAY[${userAttributes.interestInTerra.getOrElse(Array.empty[String])}]::text[], - ${userAttributes.programLocationCity}, - ${userAttributes.programLocationState}, - ${userAttributes.programLocationCountry}, - ARRAY[${userAttributes.researchArea.getOrElse(Array.empty[String])}]::text[], - ${userAttributes.additionalAttributes.getOrElse("{}")}::jsonb, - ${Instant.now()}, - ${Instant.now()} - ) + insert into ${UserAttributesTable as userAttributesTable} (${userAttributesColumns.samUserId}, ${userAttributesColumns.marketingConsent}, ${userAttributesColumns.updatedAt}) + values (${userAttributes.userId}, ${userAttributes.marketingConsent}, ${Instant.now()}) on conflict(${userAttributesColumns.samUserId}) - do update set - ${userAttributesColumns.marketingConsent} = ${userAttributes.marketingConsent}, - ${userAttributesColumns.firstName} = ${userAttributes.firstName}, - ${userAttributesColumns.lastName} = ${userAttributes.lastName}, - ${userAttributesColumns.organization} = ${userAttributes.organization}, - ${userAttributesColumns.contactEmail} = ${userAttributes.contactEmail}, - ${userAttributesColumns.title} = ${userAttributes.title}, - ${userAttributesColumns.department} = ${userAttributes.department}, - ${userAttributesColumns.interestInTerra} = ARRAY[${userAttributes.interestInTerra.getOrElse(Array.empty[String])}]::text[], - ${userAttributesColumns.programLocationCity} = ${userAttributes.programLocationCity}, - ${userAttributesColumns.programLocationState} = ${userAttributes.programLocationState}, - ${userAttributesColumns.programLocationCountry} = ${userAttributes.programLocationCountry}, - ${userAttributesColumns.researchArea} = ARRAY[${userAttributes.researchArea.getOrElse(Array.empty[String])}]::text[], - ${userAttributesColumns.additionalAttributes} = ${userAttributes.additionalAttributes.getOrElse("{}")}::jsonb, - ${userAttributesColumns.updatedAt} = ${Some(Instant.now())} + do update set ${userAttributesColumns.marketingConsent} = ${userAttributes.marketingConsent}, + ${userAttributesColumns.updatedAt} = ${Instant.now()} """.update().apply() > 0 } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/SamTypeBinders.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/SamTypeBinders.scala index 3be879e94..9ed071b45 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/SamTypeBinders.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/SamTypeBinders.scala @@ -16,13 +16,6 @@ import org.broadinstitute.dsde.workbench.sam.model._ import scalikejdbc.TypeBinder object SamTypeBinders { - implicit val optionListStringTypeBinder: TypeBinder[Option[List[String]]] = new TypeBinder[Option[List[String]]] { - def apply(rs: ResultSet, label: String): Option[List[String]] = - Option(rs.getArray(label)).map(_.getArray.asInstanceOf[Array[String]].toList) - def apply(rs: ResultSet, index: Int): Option[List[String]] = - Option(rs.getArray(index)).map(_.getArray.asInstanceOf[Array[String]].toList) - } - implicit val accessInstructionsPKTypeBinder: TypeBinder[AccessInstructionsPK] = new TypeBinder[AccessInstructionsPK] { def apply(rs: ResultSet, label: String): AccessInstructionsPK = AccessInstructionsPK(rs.getLong(label)) def apply(rs: ResultSet, index: Int): AccessInstructionsPK = AccessInstructionsPK(rs.getLong(index)) diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserAttributesTable.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserAttributesTable.scala index 6dcee8f95..83ac3ac92 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserAttributesTable.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/db/tables/UserAttributesTable.scala @@ -4,25 +4,13 @@ import org.broadinstitute.dsde.workbench.model._ import org.broadinstitute.dsde.workbench.sam.db.SamTypeBinders import org.broadinstitute.dsde.workbench.sam.model.api.SamUserAttributes import scalikejdbc._ + import java.time.Instant final case class UserAttributesRecord( samUserId: WorkbenchUserId, marketingConsent: Boolean, - firstName: Option[String], - lastName: Option[String], - organization: Option[String], - contactEmail: Option[String], - title: Option[String], - department: Option[String], - interestInTerra: Option[List[String]], - programLocationCity: Option[String], - programLocationState: Option[String], - programLocationCountry: Option[String], - researchArea: Option[List[String]], - additionalAttributes: Option[String], - createdAt: Option[Instant], - updatedAt: Option[Instant] + updatedAt: Instant ) object UserAttributesTable extends SQLSyntaxSupportWithDefaultSamDB[UserAttributesRecord] { @@ -32,19 +20,6 @@ object UserAttributesTable extends SQLSyntaxSupportWithDefaultSamDB[UserAttribut def apply(e: ResultName[UserAttributesRecord])(rs: WrappedResultSet): UserAttributesRecord = UserAttributesRecord( rs.get(e.samUserId), rs.get(e.marketingConsent), - rs.get(e.firstName), - rs.get(e.lastName), - rs.get(e.organization), - rs.get(e.contactEmail), - rs.get(e.title), - rs.get(e.department), - rs.get(e.interestInTerra), - rs.get(e.programLocationCity), - rs.get(e.programLocationState), - rs.get(e.programLocationCountry), - rs.get(e.researchArea), - rs.get(e.additionalAttributes), - rs.get(e.createdAt), rs.get(e.updatedAt) ) @@ -53,20 +28,6 @@ object UserAttributesTable extends SQLSyntaxSupportWithDefaultSamDB[UserAttribut def unmarshalUserAttributesRecord(userAttributesRecord: UserAttributesRecord): SamUserAttributes = SamUserAttributes( userAttributesRecord.samUserId, - userAttributesRecord.marketingConsent, - userAttributesRecord.firstName, - userAttributesRecord.lastName, - userAttributesRecord.organization, - userAttributesRecord.contactEmail, - userAttributesRecord.title, - userAttributesRecord.department, - userAttributesRecord.interestInTerra, - userAttributesRecord.programLocationCity, - userAttributesRecord.programLocationState, - userAttributesRecord.programLocationCountry, - userAttributesRecord.researchArea, - userAttributesRecord.additionalAttributes, - userAttributesRecord.createdAt, - userAttributesRecord.updatedAt + userAttributesRecord.marketingConsent ) } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributes.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributes.scala index b9a0d0293..25ac39c60 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributes.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributes.scala @@ -5,49 +5,17 @@ import akka.http.scaladsl.model.StatusCodes import cats.effect.IO import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport.WorkbenchUserIdFormat import org.broadinstitute.dsde.workbench.model.{ErrorReport, WorkbenchExceptionWithErrorReport, WorkbenchUserId} +import spray.json.DefaultJsonProtocol.jsonFormat2 import spray.json.DefaultJsonProtocol._ import spray.json.RootJsonFormat -import org.broadinstitute.dsde.workbench.model.google.GoogleModelJsonSupport.InstantFormat - -import java.time.Instant object SamUserAttributes { - implicit val SamUserAttributesFormat: RootJsonFormat[SamUserAttributes] = jsonFormat16(SamUserAttributes.apply) + implicit val SamUserAttributesFormat: RootJsonFormat[SamUserAttributes] = jsonFormat2(SamUserAttributes.apply) def newUserAttributesFromRequest(userId: WorkbenchUserId, userAttributesRequest: SamUserAttributesRequest): IO[SamUserAttributes] = { val samUserAttributes = for { marketingConsent <- userAttributesRequest.marketingConsent - firstName = userAttributesRequest.firstName - lastName = userAttributesRequest.lastName - organization = userAttributesRequest.organization - contactEmail = userAttributesRequest.contactEmail - title = userAttributesRequest.title - department = userAttributesRequest.department - interestInTerra = userAttributesRequest.interestInTerra - programLocationCity = userAttributesRequest.programLocationCity - programLocationState = userAttributesRequest.programLocationState - programLocationCountry = userAttributesRequest.programLocationCountry - researchArea = userAttributesRequest.researchArea - additionalAttributes = userAttributesRequest.additionalAttributes - - } yield SamUserAttributes( - userId, - marketingConsent, - firstName, - lastName, - organization, - contactEmail, - title, - department, - interestInTerra, - programLocationCity, - programLocationState, - programLocationCountry, - researchArea, - additionalAttributes, - Some(Instant.now()), - Some(Instant.now()) - ) + } yield SamUserAttributes(userId, marketingConsent) IO.fromOption(samUserAttributes)( new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.BadRequest, s"Missing values required for new user attributes.")) ) @@ -55,41 +23,7 @@ object SamUserAttributes { } } -final case class SamUserAttributes( - userId: WorkbenchUserId, - marketingConsent: Boolean, - firstName: Option[String], - lastName: Option[String], - organization: Option[String], - contactEmail: Option[String], - title: Option[String], - department: Option[String], - interestInTerra: Option[List[String]], - programLocationCity: Option[String], - programLocationState: Option[String], - programLocationCountry: Option[String], - researchArea: Option[List[String]], - additionalAttributes: Option[String], - createdAt: Option[Instant], - updatedAt: Option[Instant] -) { - def updateFromUserAttributesRequest(userId: WorkbenchUserId, userAttributesRequest: SamUserAttributesRequest): IO[SamUserAttributes] = - IO( - this.copy( - userId = userId, - marketingConsent = userAttributesRequest.marketingConsent.getOrElse(this.marketingConsent), - firstName = userAttributesRequest.firstName.orElse(this.firstName), - lastName = userAttributesRequest.lastName.orElse(this.lastName), - organization = userAttributesRequest.organization.orElse(this.organization), - contactEmail = userAttributesRequest.contactEmail.orElse(this.contactEmail), - title = userAttributesRequest.title.orElse(this.title), - department = userAttributesRequest.department.orElse(this.department), - interestInTerra = userAttributesRequest.interestInTerra.orElse(this.interestInTerra), - programLocationCity = userAttributesRequest.programLocationCity.orElse(this.programLocationCity), - programLocationState = userAttributesRequest.programLocationState.orElse(this.programLocationState), - programLocationCountry = userAttributesRequest.programLocationCountry.orElse(this.programLocationCountry), - researchArea = userAttributesRequest.researchArea.orElse(this.researchArea), - additionalAttributes = userAttributesRequest.additionalAttributes.orElse(this.additionalAttributes) - ) - ) +final case class SamUserAttributes(userId: WorkbenchUserId, marketingConsent: Boolean) { + def updateFromUserAttributesRequest(userAttributesRequest: SamUserAttributesRequest): IO[SamUserAttributes] = + IO(this.copy(marketingConsent = userAttributesRequest.marketingConsent.getOrElse(this.marketingConsent))) } diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributesRequest.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributesRequest.scala index 75eb1a76c..29dfaa07b 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributesRequest.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/model/api/SamUserAttributesRequest.scala @@ -1,30 +1,17 @@ package org.broadinstitute.dsde.workbench.sam package model.api -import org.broadinstitute.dsde.workbench.model.WorkbenchIdentityJsonSupport.WorkbenchUserIdFormat -import org.broadinstitute.dsde.workbench.model.{ErrorReport, WorkbenchUserId} +import org.broadinstitute.dsde.workbench.model.ErrorReport +import spray.json.DefaultJsonProtocol.jsonFormat1 import spray.json.DefaultJsonProtocol._ import spray.json.RootJsonFormat object SamUserAttributesRequest { - implicit val SamUserAttributesRequestFormat: RootJsonFormat[SamUserAttributesRequest] = jsonFormat14(SamUserAttributesRequest.apply) + implicit val SamUserAttributesRequestFormat: RootJsonFormat[SamUserAttributesRequest] = jsonFormat1(SamUserAttributesRequest.apply) } case class SamUserAttributesRequest( - userId: WorkbenchUserId, - marketingConsent: Option[Boolean], - firstName: Option[String], - lastName: Option[String], - organization: Option[String], - contactEmail: Option[String], - title: Option[String], - department: Option[String], - interestInTerra: Option[List[String]], - programLocationCity: Option[String], - programLocationState: Option[String], - programLocationCountry: Option[String], - researchArea: Option[List[String]], - additionalAttributes: Option[String] + marketingConsent: Option[Boolean] ) { def validateForNewUser: Option[Seq[ErrorReport]] = Option( Seq( diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala index 321497f28..5972106ad 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/UserService.scala @@ -97,40 +97,11 @@ class UserService( private def registerNewUserAttributes( userId: WorkbenchUserId, registrationRequest: Option[SamUserRegistrationRequest], - samRequestContext: SamRequestContext, - firstName: Option[String] = None, - lastName: Option[String] = None, - organization: Option[String] = None, - contactEmail: Option[String] = None, - title: Option[String] = None, - department: Option[String] = None, - interestInTerra: Option[List[String]] = None, - programLocationCity: Option[String] = None, - programLocationState: Option[String] = None, - programLocationCountry: Option[String] = None, - researchArea: Option[List[String]] = None, - additionalAttributes: Option[String] = None + samRequestContext: SamRequestContext ): IO[Unit] = { val attributes = registrationRequest .map(_.userAttributes) - .getOrElse( - SamUserAttributesRequest( - userId = userId, - marketingConsent = Some(false), - firstName = firstName, - lastName = lastName, - organization = organization, - contactEmail = contactEmail, - title = title, - department = department, - interestInTerra = interestInTerra, - programLocationCity = programLocationCity, - programLocationState = programLocationState, - programLocationCountry = programLocationCountry, - researchArea = researchArea, - additionalAttributes = additionalAttributes - ) - ) + .getOrElse(SamUserAttributesRequest(marketingConsent = Some(false))) setUserAttributesFromRequest(userId, attributes, samRequestContext).map(_ => ()) } @@ -287,27 +258,7 @@ class UserService( case Some(_) => IO.raiseError(new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.Conflict, s"email ${inviteeEmail} already exists"))) } - _ <- setUserAttributes( - SamUserAttributes( - createdUser.id, - marketingConsent = false, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None - ), - samRequestContext - ) + _ <- setUserAttributes(SamUserAttributes(createdUser.id, marketingConsent = false), samRequestContext) } yield UserStatusDetails(createdUser.id, createdUser.email) private def createUserInternal(user: SamUser, samRequestContext: SamRequestContext): IO[SamUser] = @@ -529,7 +480,7 @@ class UserService( userAttributesOpt <- getUserAttributes(userId, samRequestContext) updatedAttributes <- userAttributesOpt match { case Some(currentUserAttributes) => - currentUserAttributes.updateFromUserAttributesRequest(userId, userAttributesRequest) + currentUserAttributes.updateFromUserAttributesRequest(userAttributesRequest) case None => SamUserAttributes.newUserAttributesFromRequest(userId, userAttributesRequest) } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala index cbc3aeafc..a8821151f 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/UserRoutesV2Spec.scala @@ -40,43 +40,10 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with val thirdUser: SamUser = Generator.genWorkbenchUserGoogle.sample.get val adminGroupEmail: WorkbenchEmail = Generator.genFirecloudEmail.sample.get val allUsersGroup: BasicWorkbenchGroup = BasicWorkbenchGroup(CloudExtensions.allUsersGroupName, Set(), WorkbenchEmail("all_users@fake.com")) - val userAttributesRequest = SamUserAttributesRequest( - userId = defaultUser.id, - marketingConsent = Some(true), - firstName = Some("firstName"), - lastName = Some("lastName"), - organization = Some("organization"), - contactEmail = Some("contactEmail"), - title = Some("title"), - department = Some("department"), - interestInTerra = Some(List("interestInTerra")), - programLocationCity = Some("programLocationCity"), - programLocationState = Some("programLocationState"), - programLocationCountry = Some("programLocationCountry"), - researchArea = Some(List("researchArea")), - additionalAttributes = Some("""{"additionalAttributes": "foo"}""") - ) - val userAttributes = SamUserAttributes( - defaultUser.id, - marketingConsent = true, - firstName = Some("firstName"), - lastName = Some("lastName"), - organization = Some("organization"), - contactEmail = Some("contactEmail"), - title = Some("title"), - department = Some("department"), - interestInTerra = Some(List("interestInTerra")), - programLocationCity = Some("programLocationCity"), - programLocationState = Some("programLocationState"), - programLocationCountry = Some("programLocationCountry"), - researchArea = Some(List("researchArea")), - additionalAttributes = Some("""{"additionalAttributes": "foo"}"""), - createdAt = Some(Instant.now()), - updatedAt = Some(Instant.now()) - ) "POST /api/users/v2/self/register" should "register a user when the required attributes are provided" in { // Arrange + val userAttributesRequest = SamUserAttributesRequest(marketingConsent = Some(false)) val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUser(defaultUser) .withAllowedUser(defaultUser) @@ -226,6 +193,8 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with "GET /api/users/v2/self/attributes" should "get the user attributes of the calling user" in { // Arrange + val userAttributes = SamUserAttributes(defaultUser.id, marketingConsent = true) + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUser(defaultUser) // "persisted/enabled" user we will check the status of .withAllowedUser(defaultUser) // "allowed" user we will check the status of @@ -242,6 +211,8 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with "GET /api/users/v2/self/attributes" should "get the user attributes of the calling disallowed user" in { // Arrange + val userAttributes = SamUserAttributes(defaultUser.id, marketingConsent = true) + val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withDisabledUser(defaultUser) .withDisallowedUser(defaultUser) @@ -272,58 +243,26 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with "PATCH /api/users/v2/self/attributes" should "update the user attributes of the calling user" in { // Arrange - val updatedUserAttributesRequest = SamUserAttributesRequest( - defaultUser.id, - marketingConsent = Some(false), - firstName = Some("newFirstName"), - lastName = Some("newLastName"), - organization = Some("newOrganization"), - contactEmail = Some("newContactEmail"), - title = Some("newTitle"), - department = Some("newDepartment"), - interestInTerra = Some(List("NewInterestInTerra")), - programLocationCity = Some("NewProgramLocationCity"), - programLocationState = Some("NewProgramLocationState"), - programLocationCountry = Some("NewProgramLocationCountry"), - researchArea = Some(List("NewResearchArea")), - additionalAttributes = Some("""{"additionalAttributes": "bar"}""") - ) - - val updatedUserAttributes = SamUserAttributes( - defaultUser.id, - marketingConsent = false, - firstName = Some("newFirstName"), - lastName = Some("newLastName"), - organization = Some("newOrganization"), - contactEmail = Some("newContactEmail"), - title = Some("newTitle"), - department = Some("newDepartment"), - interestInTerra = Some(List("NewInterestInTerra")), - programLocationCity = Some("NewProgramLocationCity"), - programLocationState = Some("NewProgramLocationState"), - programLocationCountry = Some("NewProgramLocationCountry"), - researchArea = Some(List("NewResearchArea")), - additionalAttributes = Some("""{"additionalAttributes": "bar"}"""), - createdAt = None, - updatedAt = Some(Instant.now()) - ) + val userAttributesRequest = SamUserAttributesRequest(marketingConsent = Some(false)) + val userAttributes = SamUserAttributes(defaultUser.id, marketingConsent = false) val samRoutes = new MockSamRoutesBuilder(allUsersGroup) .withEnabledUser(defaultUser) // "persisted/enabled" user we will check the status of .withAllowedUser(defaultUser) // "allowed" user we will check the status of - .withUserAttributes(defaultUser, updatedUserAttributes) + .withUserAttributes(defaultUser, userAttributes) .callAsNonAdminUser() .build // Act and Assert - Patch(s"/api/users/v2/self/attributes", updatedUserAttributesRequest) ~> samRoutes.route ~> check { + Patch(s"/api/users/v2/self/attributes", userAttributesRequest) ~> samRoutes.route ~> check { status shouldEqual StatusCodes.OK - responseAs[SamUserAttributes] should be(updatedUserAttributes) + responseAs[SamUserAttributes] should be(userAttributes) } } "GET /api/users/v2/self/combinedState" should "get the user combined state of the calling user" in { // Arrange + val userAttributes = SamUserAttributes(defaultUser.id, marketingConsent = true) val favoriteResources = Set(FullyQualifiedResourceId(ResourceTypeName("workspaceType"), ResourceId("workspaceName"))) val enterpriseFeature = FilteredResourceFlat( resourceType = ResourceTypeName("enterprise-feature"), @@ -334,13 +273,11 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with authDomainGroups = Set.empty, missingAuthDomainGroups = Set.empty ) - val filteredResourcesFlat = FilteredResourcesFlat(Set(enterpriseFeature)) + val filteresResourcesFlat = FilteredResourcesFlat(Set(enterpriseFeature)) val userCombinedStateResponse = SamUserCombinedStateResponse( defaultUser, SamUserAllowances(enabled = true, termsOfService = true), - Option( - userAttributes - ), + Option(SamUserAttributes(defaultUser.id, marketingConsent = true)), TermsOfServiceDetails(Option("v1"), Option(Instant.now()), permitsSystemUsage = true, isCurrentVersion = true), Map("enterpriseFeatures" -> FilteredResourcesFlat(Set(enterpriseFeature)).toJson), favoriteResources @@ -382,7 +319,7 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with response.termsOfServiceDetails.isCurrentVersion should be(userCombinedStateResponse.termsOfServiceDetails.isCurrentVersion) response.termsOfServiceDetails.permitsSystemUsage should be(userCombinedStateResponse.termsOfServiceDetails.permitsSystemUsage) response.termsOfServiceDetails.latestAcceptedVersion should be(userCombinedStateResponse.termsOfServiceDetails.latestAcceptedVersion) - response.additionalDetails should be(Map("enterpriseFeatures" -> filteredResourcesFlat.toJson)) + response.additionalDetails should be(Map("enterpriseFeatures" -> filteresResourcesFlat.toJson)) response.favoriteResources should be(favoriteResources) } } @@ -398,30 +335,11 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with authDomainGroups = Set.empty, missingAuthDomainGroups = Set.empty ) - val filteredResourcesFlat = FilteredResourcesFlat(Set(enterpriseFeature)) + val filteresResourcesFlat = FilteredResourcesFlat(Set(enterpriseFeature)) val userCombinedStateResponse = SamUserCombinedStateResponse( defaultUser, SamUserAllowances(enabled = true, termsOfService = true), - Option( - SamUserAttributes( - defaultUser.id, - marketingConsent = true, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None - ) - ), + Option(SamUserAttributes(defaultUser.id, marketingConsent = true)), TermsOfServiceDetails(Option("v1"), Option(Instant.now()), permitsSystemUsage = true, isCurrentVersion = true), Map("enterpriseFeatures" -> FilteredResourcesFlat(Set(enterpriseFeature)).toJson), Set.empty @@ -462,7 +380,7 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with response.termsOfServiceDetails.isCurrentVersion should be(userCombinedStateResponse.termsOfServiceDetails.isCurrentVersion) response.termsOfServiceDetails.permitsSystemUsage should be(userCombinedStateResponse.termsOfServiceDetails.permitsSystemUsage) response.termsOfServiceDetails.latestAcceptedVersion should be(userCombinedStateResponse.termsOfServiceDetails.latestAcceptedVersion) - response.additionalDetails should be(Map("enterpriseFeatures" -> filteredResourcesFlat.toJson)) + response.additionalDetails should be(Map("enterpriseFeatures" -> filteresResourcesFlat.toJson)) } } @@ -473,26 +391,7 @@ class UserRoutesV2Spec extends AnyFlatSpec with Matchers with TimeMatchers with val userCombinedStateResponse = SamUserCombinedStateResponse( defaultUser, SamUserAllowances(enabled = false, termsOfService = false), - Option( - SamUserAttributes( - defaultUser.id, - marketingConsent = true, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None - ) - ), + Option(SamUserAttributes(defaultUser.id, marketingConsent = true)), TermsOfServiceDetails(None, None, permitsSystemUsage = false, isCurrentVersion = false), Map("enterpriseFeatures" -> filteredResourcesFlat.toJson), Set.empty diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala index 43a81246e..fcb0d910a 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala @@ -1893,46 +1893,14 @@ class PostgresDirectoryDAOSpec extends RetryableAnyFreeSpec with Matchers with B // Arrange val expectedUser = defaultUser.copy(registeredAt = Some(Instant.now())) val createdUser = dao.createUser(expectedUser, samRequestContext).unsafeRunSync() - val userAttributes = SamUserAttributes( - createdUser.id, - marketingConsent = true, - firstName = Some("firstName"), - lastName = Some("lastName"), - organization = Some("organization"), - contactEmail = Some("contactEmail"), - title = Some("title"), - department = Some("department"), - interestInTerra = Some(List("interestInTerra")), - programLocationCity = Some("programLocationCity"), - programLocationState = Some("programLocationState"), - programLocationCountry = Some("programLocationCountry"), - researchArea = Some(List("researchArea")), - additionalAttributes = Some("""{"additionalAttributes": "foo"}"""), - None, - None - ) + val userAttributes = SamUserAttributes(createdUser.id, marketingConsent = true) dao.setUserAttributes(userAttributes, samRequestContext).unsafeRunSync() // Act val retrievedAttributes = dao.getUserAttributes(createdUser.id, samRequestContext).unsafeRunSync() // Assert - retrievedAttributes.get.marketingConsent should be(true) - retrievedAttributes.get.firstName should be(Some("firstName")) - retrievedAttributes.get.lastName should be(Some("lastName")) - retrievedAttributes.get.organization should be(Some("organization")) - retrievedAttributes.get.contactEmail should be(Some("contactEmail")) - retrievedAttributes.get.title should be(Some("title")) - retrievedAttributes.get.department should be(Some("department")) - retrievedAttributes.get.interestInTerra should be(Some(List("interestInTerra"))) - retrievedAttributes.get.programLocationCity should be(Some("programLocationCity")) - retrievedAttributes.get.programLocationState should be(Some("programLocationState")) - retrievedAttributes.get.programLocationCountry should be(Some("programLocationCountry")) - retrievedAttributes.get.researchArea should be(Some(List("researchArea"))) - retrievedAttributes.get.additionalAttributes should be(Some("""{"additionalAttributes": "foo"}""")) - retrievedAttributes.get.createdAt.get should beAround(Instant.now()) - retrievedAttributes.get.updatedAt.get should beAround(Instant.now()) - + retrievedAttributes should be(Some(userAttributes)) } "returns None if no user attributes exist" in { @@ -1965,47 +1933,16 @@ class PostgresDirectoryDAOSpec extends RetryableAnyFreeSpec with Matchers with B // Arrange val expectedUser = defaultUser.copy(registeredAt = Some(Instant.now())) val createdUser = dao.createUser(expectedUser, samRequestContext).unsafeRunSync() - val userAttributes = SamUserAttributes( - createdUser.id, - marketingConsent = true, - firstName = Some("firstName"), - lastName = Some("lastName"), - organization = Some("organization"), - contactEmail = Some("contactEmail"), - title = Some("title"), - department = Some("department"), - interestInTerra = Some(List("interestInTerra")), - programLocationCity = Some("programLocationCity"), - programLocationState = Some("programLocationState"), - programLocationCountry = Some("programLocationCountry"), - researchArea = Some(List("researchArea")), - additionalAttributes = Some("""{"additionalAttributes": "foo"}"""), - None, - None - ) + val userAttributes = SamUserAttributes(createdUser.id, marketingConsent = true) dao.setUserAttributes(userAttributes, samRequestContext).unsafeRunSync() // Act - val upsertedAttributes = userAttributes.copy(marketingConsent = false, firstName = Some("newFirstName")) + val upsertedAttributes = userAttributes.copy(marketingConsent = false) dao.setUserAttributes(upsertedAttributes, samRequestContext).unsafeRunSync() val retrievedAttributes = dao.getUserAttributes(expectedUser.id, samRequestContext).unsafeRunSync() // Assert - retrievedAttributes.get.marketingConsent should be(false) - retrievedAttributes.get.firstName should be(Some("newFirstName")) - retrievedAttributes.get.lastName should be(Some("lastName")) - retrievedAttributes.get.organization should be(Some("organization")) - retrievedAttributes.get.contactEmail should be(Some("contactEmail")) - retrievedAttributes.get.title should be(Some("title")) - retrievedAttributes.get.department should be(Some("department")) - retrievedAttributes.get.interestInTerra should be(Some(List("interestInTerra"))) - retrievedAttributes.get.programLocationCity should be(Some("programLocationCity")) - retrievedAttributes.get.programLocationState should be(Some("programLocationState")) - retrievedAttributes.get.programLocationCountry should be(Some("programLocationCountry")) - retrievedAttributes.get.researchArea should be(Some(List("researchArea"))) - retrievedAttributes.get.additionalAttributes should be(Some("""{"additionalAttributes": "foo"}""")) - retrievedAttributes.get.createdAt.get should beAround(Instant.now()) - retrievedAttributes.get.updatedAt.get should beAround(Instant.now()) + retrievedAttributes should be(Some(upsertedAttributes)) } } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala index 204c864f4..beced2ce3 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/MockUserServiceBuilder.scala @@ -214,22 +214,7 @@ case class MockUserServiceBuilder() extends IdiomaticMockito { mockUserService.setUserAttributes(argThat((attr: SamUserAttributes) => attr.userId.equals(userId)), any[SamRequestContext]) returns IO(userAttributes) mockUserService.setUserAttributesFromRequest( eqTo(userId), - SamUserAttributesRequest( - userId, - Some(userAttributes.marketingConsent), - userAttributes.firstName, - userAttributes.lastName, - userAttributes.organization, - userAttributes.contactEmail, - userAttributes.title, - userAttributes.department, - userAttributes.interestInTerra, - userAttributes.programLocationCity, - userAttributes.programLocationState, - userAttributes.programLocationCountry, - userAttributes.researchArea, - userAttributes.additionalAttributes - ), + SamUserAttributesRequest(Some(userAttributes.marketingConsent)), any[SamRequestContext] ) returns IO(userAttributes) } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala index 1508b45e0..47b6c1db2 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/CreateUserSpec.scala @@ -14,7 +14,6 @@ import org.mockito.ArgumentMatchersSugar.{any, eqTo} import org.mockito.Mockito.verify import org.scalatest.DoNotDiscover -import java.time.Instant import scala.concurrent.ExecutionContextExecutor @DoNotDiscover @@ -123,61 +122,20 @@ class CreateUserSpec extends UserServiceTestTraits { it("with a valid registration request body") { // Arrange val newUserWithBothCloudIds = genWorkbenchUserBoth.sample.get - val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup) - .withUserAttributes( - SamUserAttributes( - newUserWithBothCloudIds.id, - false, - Some("firstName"), - Some("lastName"), - Some("organization"), - Some("contactEmail"), - Some("title"), - Some("department"), - None, - None, - None, - None, - None, - None, - Some(Instant.parse("2022-01-01T00:00:00Z")), - Some(Instant.parse("2023-01-01T00:00:00Z")) - ) - ) - .build + val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup).build val cloudExtensions: CloudExtensions = MockCloudExtensionsBuilder(allUsersGroup).build val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, defaultTosService) val userRegistrationRequest = SamUserRegistrationRequest( acceptsTermsOfService = true, - SamUserAttributesRequest( - newUserWithBothCloudIds.id, - marketingConsent = Some(false), - firstName = Some("firstName"), - lastName = Some("lastName"), - organization = Some("organization"), - contactEmail = Some("contactEmail"), - title = Some("title"), - department = Some("department"), - interestInTerra = None, - programLocationCity = None, - programLocationState = None, - programLocationCountry = None, - researchArea = None, - additionalAttributes = None - ) + SamUserAttributesRequest(marketingConsent = Some(false)) ) // Act val newUsersStatus = runAndWait(userService.createUser(newUserWithBothCloudIds, Some(userRegistrationRequest), samRequestContext)) - val actualAttributes = runAndWait(userService.getUserAttributes(newUsersStatus.userInfo.userSubjectId, samRequestContext)) // Assert - verify(directoryDAO).setUserAttributes( - actualAttributes.get, - samRequestContext - ) - + verify(directoryDAO).setUserAttributes(SamUserAttributes(newUsersStatus.userInfo.userSubjectId, marketingConsent = false), samRequestContext) verify(defaultTosService).acceptCurrentTermsOfService(newUsersStatus.userInfo.userSubjectId, samRequestContext) } } @@ -299,7 +257,7 @@ class CreateUserSpec extends UserServiceTestTraits { val invalidRegistrationRequest = SamUserRegistrationRequest( acceptsTermsOfService = true, - SamUserAttributesRequest(userWithoutIds.id, marketingConsent = None, None, None, None, None, None, None, None, None, None, None, None, None) + SamUserAttributesRequest(marketingConsent = None) ) // Act and Assert @@ -317,22 +275,7 @@ class CreateUserSpec extends UserServiceTestTraits { val invalidRegistrationRequest = SamUserRegistrationRequest( acceptsTermsOfService = false, - SamUserAttributesRequest( - userWithoutIds.id, - marketingConsent = None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None - ) + SamUserAttributesRequest(marketingConsent = None) ) // Act and Assert @@ -480,27 +423,7 @@ class CreateUserSpec extends UserServiceTestTraits { val invitedUserStatus = runAndWait(userService.inviteUser(invitedGoogleUser.email, samRequestContext)) // Assert - verify(directoryDAO).setUserAttributes( - SamUserAttributes( - invitedUserStatus.userSubjectId, - marketingConsent = false, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None - ), - samRequestContext - ) + verify(directoryDAO).setUserAttributes(SamUserAttributes(invitedUserStatus.userSubjectId, marketingConsent = false), samRequestContext) } describe("should be able to register") { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/UserAttributesSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/UserAttributesSpec.scala index 8da9b857e..7fc6eb25d 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/UserAttributesSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/UserServiceSpecs/UserAttributesSpec.scala @@ -4,17 +4,15 @@ import org.broadinstitute.dsde.workbench.model.WorkbenchEmail import org.broadinstitute.dsde.workbench.sam.Generator.genWorkbenchUserBoth import org.broadinstitute.dsde.workbench.sam.dataAccess.{DirectoryDAO, MockDirectoryDaoBuilder} import org.broadinstitute.dsde.workbench.sam.model.BasicWorkbenchGroup -import org.broadinstitute.dsde.workbench.sam.model.api.{SamUser, SamUserAttributes, SamUserAttributesRequest, SamUserRegistrationRequest} +import org.broadinstitute.dsde.workbench.sam.model.api.{SamUserAttributes, SamUserAttributesRequest, SamUserRegistrationRequest} import org.broadinstitute.dsde.workbench.sam.service.{CloudExtensions, MockCloudExtensionsBuilder, MockTosServiceBuilder, TosService, UserService} import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.mockito.ArgumentMatchersSugar.{any, eqTo} import org.mockito.Mockito.verify -import java.time.Instant import scala.concurrent.ExecutionContextExecutor -import org.broadinstitute.dsde.workbench.sam.matchers.TimeMatchers -class UserAttributesSpec extends UserServiceTestTraits with TimeMatchers { +class UserAttributesSpec extends UserServiceTestTraits { implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global val allUsersGroup: BasicWorkbenchGroup = BasicWorkbenchGroup(CloudExtensions.allUsersGroupName, Set(), WorkbenchEmail("all_users@fake.com")) @@ -22,43 +20,20 @@ class UserAttributesSpec extends UserServiceTestTraits with TimeMatchers { val cloudExtensions: CloudExtensions = MockCloudExtensionsBuilder(allUsersGroup).build val tosService: TosService = MockTosServiceBuilder().withAllAccepted().build - val user: SamUser = genWorkbenchUserBoth.sample.get.copy(enabled = true) - val userAttributes: SamUserAttributes = new SamUserAttributes( - user.id, - marketingConsent = true, - firstName = Some("firstName"), - lastName = Some("lastName"), - organization = Some("organization"), - contactEmail = Some("contactEmail"), - title = Some("title"), - department = Some("department"), - interestInTerra = Some(List("interestInTerra")), - programLocationCity = Some("programLocationCity"), - programLocationState = Some("programLocationState"), - programLocationCountry = Some("programLocationCountry"), - researchArea = Some(List("researchArea")), - additionalAttributes = Some("""{"additionalAttributes": "foo"}"""), - createdAt = Some(Instant.parse("2022-01-01T00:00:00Z")), - updatedAt = Some(Instant.parse("2023-01-01T00:00:00Z")) - ) - val newUpdatedAt: Option[Instant] = Some(Instant.parse("2024-01-01T00:00:00Z")) - describe("user attributes") { + val user = genWorkbenchUserBoth.sample.get.copy(enabled = true) it("should be retrieved for a user") { // Arrange val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup) - .withUserAttributes(userAttributes) + .withUserAttributes(SamUserAttributes(user.id, marketingConsent = true)) .build val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) - // Act val response = runAndWait(userService.getUserAttributes(user.id, samRequestContext)) // Assert - response should be( - Some(userAttributes) - ) + response should be(Some(SamUserAttributes(user.id, marketingConsent = true))) verify(directoryDAO).getUserAttributes(eqTo(user.id), any[SamRequestContext]) } @@ -66,133 +41,31 @@ class UserAttributesSpec extends UserServiceTestTraits with TimeMatchers { // Arrange val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup).build val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) - val userAttributesRequest = SamUserAttributesRequest( - user.id, - marketingConsent = Some(true), - userAttributes.firstName, - userAttributes.lastName, - userAttributes.organization, - userAttributes.contactEmail, - userAttributes.title, - userAttributes.department, - userAttributes.interestInTerra, - None, - None, - None, - None, - None - ) + val userAttributesRequest = SamUserAttributesRequest(marketingConsent = Some(true)) // Act val response = runAndWait(userService.setUserAttributesFromRequest(user.id, userAttributesRequest, samRequestContext)) // Assert - val newUserAttributes = SamUserAttributes( - user.id, - marketingConsent = true, - userAttributesRequest.firstName, - userAttributesRequest.lastName, - userAttributesRequest.organization, - userAttributesRequest.contactEmail, - userAttributesRequest.title, - userAttributesRequest.department, - userAttributesRequest.interestInTerra, - programLocationCity = None, - programLocationState = None, - programLocationCountry = None, - researchArea = None, - additionalAttributes = None, - response.createdAt, - response.updatedAt - ) - - response.userId should be(user.id) - response.marketingConsent should be(newUserAttributes.marketingConsent) - response.firstName should be(newUserAttributes.firstName) - response.lastName should be(newUserAttributes.lastName) - response.organization should be(newUserAttributes.organization) - response.contactEmail should be(newUserAttributes.contactEmail) - response.title should be(newUserAttributes.title) - response.department should be(newUserAttributes.department) - response.interestInTerra should be(newUserAttributes.interestInTerra) - response.programLocationCity should be(newUserAttributes.programLocationCity) - response.programLocationState should be(newUserAttributes.programLocationState) - response.programLocationCountry should be(newUserAttributes.programLocationCountry) - response.researchArea should be(newUserAttributes.researchArea) - response.additionalAttributes should be(newUserAttributes.additionalAttributes) - response.createdAt.get should beAround(newUserAttributes.createdAt.get) - response.updatedAt.get should beAround(newUserAttributes.updatedAt.get) + val userAttributes = SamUserAttributes(user.id, marketingConsent = true) + response should be(userAttributes) verify(directoryDAO).getUserAttributes(eqTo(user.id), any[SamRequestContext]) - verify(directoryDAO).setUserAttributes( - eqTo( - SamUserAttributes( - newUserAttributes.userId, - newUserAttributes.marketingConsent, - newUserAttributes.firstName, - newUserAttributes.lastName, - newUserAttributes.organization, - newUserAttributes.contactEmail, - newUserAttributes.title, - newUserAttributes.department, - newUserAttributes.interestInTerra, - newUserAttributes.programLocationCity, - newUserAttributes.programLocationState, - newUserAttributes.programLocationCountry, - newUserAttributes.researchArea, - newUserAttributes.additionalAttributes, - newUserAttributes.createdAt, - newUserAttributes.updatedAt - ) - ), - any[SamRequestContext] - ) + verify(directoryDAO).setUserAttributes(eqTo(userAttributes), any[SamRequestContext]) } - it("updates existing user attributes") { + it("update existing user attributes") { // Arrange + val userAttributes = SamUserAttributes(user.id, marketingConsent = true) val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup) .withUserAttributes(userAttributes) .build val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) - - val updateUserAttributesRequest = SamUserAttributesRequest( - user.id, - marketingConsent = Some(false), - firstName = Some("newFirstName"), - lastName = Some("newLastName"), - organization = Some("newOrganization"), - contactEmail = Some("newContactEmail"), - title = Some("newTitle"), - department = Some("newDepartment"), - interestInTerra = Some(List("newInterestInTerra")), - programLocationCity = None, - programLocationState = None, - programLocationCountry = Some("newProgramLocationCountry"), - researchArea = Some(List("newResearchArea")), - additionalAttributes = Some("""{"additionalAttributes": "bar"}""") - ) + val userAttributesRequest = SamUserAttributesRequest(marketingConsent = Some(false)) // Act - val response = runAndWait(userService.setUserAttributesFromRequest(user.id, updateUserAttributesRequest, samRequestContext)) + val response = runAndWait(userService.setUserAttributesFromRequest(user.id, userAttributesRequest, samRequestContext)) // Assert - val updatedUserAttributes = new SamUserAttributes( - response.userId, - response.marketingConsent, - response.firstName, - response.lastName, - response.organization, - response.contactEmail, - response.title, - response.department, - response.interestInTerra, - response.programLocationCity, - response.programLocationState, - response.programLocationCountry, - response.researchArea, - response.additionalAttributes, - response.createdAt, - response.updatedAt - ) + val updatedUserAttributes = userAttributes.copy(marketingConsent = false) response should be(updatedUserAttributes) verify(directoryDAO).getUserAttributes(eqTo(user.id), any[SamRequestContext]) @@ -201,88 +74,26 @@ class UserAttributesSpec extends UserServiceTestTraits with TimeMatchers { it("sets user attributes when a new user is registered without a request body") { // Arrange - val newUserAttributes = new SamUserAttributes( - user.id, - false, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - Some(Instant.parse("2022-01-01T00:00:00Z")), - Some(Instant.parse("2023-01-01T00:00:00Z")) - ) - val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup).withUserAttributes(newUserAttributes).build + val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup).build val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) + val userAttributes = SamUserAttributes(user.id, marketingConsent = false) // Act runAndWait(userService.createUser(user, samRequestContext)) // Assert - verify(directoryDAO).setUserAttributes( - eqTo( - SamUserAttributes( - newUserAttributes.userId, - newUserAttributes.marketingConsent, - newUserAttributes.firstName, - newUserAttributes.lastName, - newUserAttributes.organization, - newUserAttributes.contactEmail, - newUserAttributes.title, - newUserAttributes.department, - newUserAttributes.interestInTerra, - newUserAttributes.programLocationCity, - newUserAttributes.programLocationState, - newUserAttributes.programLocationCountry, - newUserAttributes.researchArea, - newUserAttributes.additionalAttributes, - newUserAttributes.createdAt, - newUserAttributes.updatedAt - ) - ), - any[SamRequestContext] - ) + verify(directoryDAO).setUserAttributes(eqTo(userAttributes), any[SamRequestContext]) } it("sets user attributes when a new user is registered with a request body") { // Arrange - val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup).withUserAttributes(userAttributes).build + val directoryDAO: DirectoryDAO = MockDirectoryDaoBuilder(allUsersGroup).build val userService: UserService = new UserService(directoryDAO, cloudExtensions, Seq.empty, tosService) + val userAttributes = SamUserAttributes(user.id, marketingConsent = true) // Act runAndWait( - userService.createUser( - user, - Some( - SamUserRegistrationRequest( - true, - SamUserAttributesRequest( - user.id, - Some(userAttributes.marketingConsent), - userAttributes.firstName, - userAttributes.lastName, - userAttributes.organization, - userAttributes.contactEmail, - userAttributes.title, - userAttributes.department, - userAttributes.interestInTerra, - userAttributes.programLocationCity, - userAttributes.programLocationState, - userAttributes.programLocationCountry, - userAttributes.researchArea, - userAttributes.additionalAttributes - ) - ) - ), - samRequestContext - ) + userService.createUser(user, Some(SamUserRegistrationRequest(true, SamUserAttributesRequest(marketingConsent = Some(true)))), samRequestContext) ) // Assert @@ -298,25 +109,9 @@ class UserAttributesSpec extends UserServiceTestTraits with TimeMatchers { val response = runAndWait(userService.inviteUser(user.email, samRequestContext)) // Assert - val userAttributes = SamUserAttributes( - response.userSubjectId, - marketingConsent = false, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None - ) + val userAttributes = SamUserAttributes(response.userSubjectId, marketingConsent = false) verify(directoryDAO).setUserAttributes(eqTo(userAttributes), any[SamRequestContext]) } + } }