Skip to content

Commit

Permalink
feat: utilize generics in UserPreferencesService (#504)
Browse files Browse the repository at this point in the history
Co-authored-by: v-gmarques <v-gmarques@mparticle.com>
  • Loading branch information
danielsiemens and gmarques-mParticle authored Nov 28, 2024
1 parent b4976bc commit 4838a86
Show file tree
Hide file tree
Showing 17 changed files with 337 additions and 338 deletions.
80 changes: 56 additions & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"@types/multer": "1.4.12",
"@typescript-eslint/eslint-plugin": "6.19.0",
"@vitejs/plugin-react": "4.2.1",
"@vitest/coverage-v8": "1.3.1",
"concurrently": "8.2.2",
"cz-conventional-changelog": "3.3.0",
"eslint": "8.56.0",
Expand Down
6 changes: 2 additions & 4 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,17 @@ export { SuiteLogo } from './navigation/GlobalNavigation/SuiteLogo'
export { Typography } from './general/Typography/Typography'

// UPS
export { UserPreferencesService } from '../services/user-preferences/user-preferences'
export { UserPreferencesService } from '../services/user-preferences'
export { CompositeUserPreferencesService } from '../services/user-preferences/composite-user-preferences-service'
export { type CompositeUserPreferences } from '../services/user-preferences/models/user-preferences/composite-user-preferences'
export {
UserPreferenceScopeType,
type UserPreferenceDefinition,
type UserPreferenceDefinitions,
type UserPreferencesPerScope,
} from '../services/user-preferences/models/definitions'
export {
type UserPreferences,
USER_PREFERENCE_SCOPE_SEPARATOR,
UserPreferenceGlobalScope,
type UserPreference,
type UserPreferenceScope,
} from '../services/user-preferences/models/storage-models'
export {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import { describe, it, expect, beforeEach } from 'vitest'
import { CompositeUserPreferencesService } from 'src/services/user-preferences/composite-user-preferences-service'
import { type UserPreferences } from 'src/services/user-preferences/models/storage-models/user-preferences'
import { type UserPreferenceScope } from 'src/services/user-preferences/models/storage-models/user-preference-scope'
import { type UserPreferenceDefinitions } from 'src/services/user-preferences/models/definitions/user-preference-definitions'
import { UserPreferenceScopeType } from 'src/services/user-preferences/models/definitions/user-preference-scope-type'
import { type UserPreferenceDefinition } from 'src/services/user-preferences/models/definitions/user-preference-definition'
import {
makeBuilderFromDefinition,
type TestType,
TestUserPreferenceDefinitionsFakeFactory,
TestUserPreferenceId,
type TestUserPreferencesFakeBuilder,
TestUserPreferencesFakeFactory,
} from 'src/services/user-preferences/user-preferences-service.spec'
import { type UserPreferenceDefinitions } from 'src/components'
import { type UserPreferencesPerScope } from '../models/definitions/user-preference-per-scope'

describe('When testing CompositeUserPreferencesService', () => {
let compositeUserPreferencesService: CompositeUserPreferencesService<TestUserPreferenceId>
let userPreferences: UserPreferences<TestUserPreferenceId>
let compositeUserPreferencesService: CompositeUserPreferencesService<TestType>
let userPreferences: UserPreferencesPerScope<TestType>
let expectedScope: UserPreferenceScope
let definitions: UserPreferenceDefinitions<TestUserPreferenceId>
let definitions: UserPreferenceDefinitions<TestType>

beforeEach(() => {
definitions = TestUserPreferenceDefinitionsFakeFactory() as UserPreferenceDefinitions<TestUserPreferenceId>
definitions = TestUserPreferenceDefinitionsFakeFactory() as UserPreferenceDefinitions<TestType>
const prefsBuilder = makeBuilderFromDefinition(definitions)
userPreferences = TestUserPreferencesFakeFactory([prefsBuilder]) as UserPreferences<TestUserPreferenceId>
userPreferences = TestUserPreferencesFakeFactory([prefsBuilder]) as UserPreferencesPerScope<TestType>
expectedScope = Object.keys(userPreferences)[0] as UserPreferenceScope

compositeUserPreferencesService = new CompositeUserPreferencesService<TestUserPreferenceId>()
compositeUserPreferencesService = new CompositeUserPreferencesService<TestType>()
})

describe('and getting scoped user preferences', () => {
Expand All @@ -42,8 +42,8 @@ describe('When testing CompositeUserPreferencesService', () => {

// assert
Object.entries(actualScopedUserPreferences).forEach(([preferenceId, actualPreference]) => {
const definition = definitions[preferenceId as TestUserPreferenceId]
const expectedScopedUserPreferences = { optedIn: definition?.isOptedInByDefault }
const definition = definitions[preferenceId as keyof TestType]
const expectedScopedUserPreferences = definition.defaultValue
expect(actualPreference).toEqual(expectedScopedUserPreferences)
})
})
Expand Down Expand Up @@ -77,21 +77,26 @@ describe('When testing CompositeUserPreferencesService', () => {
allowedScope: UserPreferenceScopeType,
) => {
// arrange
const { preferenceId: builderPreferenceId } = getFirstDefinition(definitions)
const updatingId = builderPreferenceId

const userPreferencesBuilder: TestUserPreferencesFakeBuilder[] = [
{ scope: expectedScope, userPreferenceIds: [TestUserPreferenceId.Default], optedIns: [true] },
{
scope: expectedScope,
keys: [updatingId],
defaultValues: [{ isOptedIn: true }],
},
{ wantsRandom: true },
{ wantsRandom: true },
]
userPreferences = TestUserPreferencesFakeFactory(
userPreferencesBuilder,
) as UserPreferences<TestUserPreferenceId>
userPreferences = TestUserPreferencesFakeFactory(userPreferencesBuilder) as UserPreferencesPerScope<TestType>
definitions = TestUserPreferenceDefinitionsFakeFactory([
{
id: TestUserPreferenceId.Default,
id: 'Default',
isOptedInByDefault: true,
allowedScope,
},
]) as UserPreferenceDefinitions<TestUserPreferenceId>
]) as UserPreferenceDefinitions<TestType>

// act
const actualScopedUserPreferences = compositeUserPreferencesService.getScopedUserPreferences(
Expand Down Expand Up @@ -124,32 +129,34 @@ describe('When testing CompositeUserPreferencesService', () => {
allowedScope: UserPreferenceScopeType,
) => {
// arrange
const testPreferenceValue = true
const testPreferenceValues = { isOptedIn: true }
const { preferenceId: builderPreferenceId } = getFirstDefinition(definitions)
const updatingId = builderPreferenceId

const userPreferencesBuilder: TestUserPreferencesFakeBuilder[] = [
{ scope: expectedScope, userPreferenceIds: [updatingId], optedIns: [testPreferenceValue] },
{
scope: expectedScope,
keys: [updatingId],
defaultValues: [testPreferenceValues],
},
{ wantsRandom: true },
{ wantsRandom: true },
]
userPreferences = TestUserPreferencesFakeFactory(
userPreferencesBuilder,
) as UserPreferences<TestUserPreferenceId>
userPreferences = TestUserPreferencesFakeFactory(userPreferencesBuilder) as UserPreferencesPerScope<TestType>

// act
const expectedPreferenceValue = !testPreferenceValue
const expectedValues = { isOptedIn: false }
const actualUserPreferences = compositeUserPreferencesService.getUpdatedUserPreferenceStorageObject(
updatingId,
expectedPreferenceValue,
expectedValues,
currentScope,
userPreferences,
allowedScope,
)

// assert
const actualUserPreference = actualUserPreferences?.[expectedScope]?.[updatingId]
expect(actualUserPreference?.optedIn).toEqual(expectedPreferenceValue)
expect(actualUserPreference?.isOptedIn).toEqual(expectedValues.isOptedIn)
expect(actualUserPreference).not.toBe(userPreferences)
},
)
Expand All @@ -169,35 +176,36 @@ describe('When testing CompositeUserPreferencesService', () => {
allowedScope: UserPreferenceScopeType,
) => {
// arrange
const expectedPreferenceValue = true
const updatingId = TestUserPreferenceId.Default
const expectedValues = { isOptedIn: true }
const { preferenceId: builderPreferenceId } = getFirstDefinition(definitions)
const updatingId = builderPreferenceId

userPreferences = {} satisfies UserPreferences<TestUserPreferenceId>
userPreferences = {} satisfies UserPreferencesPerScope<TestType>

// act
const actualUserPreferences = compositeUserPreferencesService.getUpdatedUserPreferenceStorageObject(
updatingId,
expectedPreferenceValue,
expectedValues,
expectedScope,
userPreferences,
allowedScope,
)

// assert
const actualUserPreference = actualUserPreferences?.[expectedScope]?.[updatingId]
expect(actualUserPreference?.optedIn).toEqual(expectedPreferenceValue)
expect(actualUserPreference?.isOptedIn).toEqual(expectedValues.isOptedIn)
expect(actualUserPreference).not.toBe(userPreferences)
},
)
})
})

function getFirstDefinition(definitions: UserPreferenceDefinitions<TestUserPreferenceId>): {
definition?: UserPreferenceDefinition
preferenceId: TestUserPreferenceId
function getFirstDefinition(definitions: UserPreferenceDefinitions<TestType>): {
definition: UserPreferenceDefinition<TestType>
preferenceId: keyof TestType
} {
const preferenceId = Object.keys(definitions)[0] as TestUserPreferenceId
const definition = definitions[preferenceId]
const preferenceId = Object.keys(definitions)[0] as keyof TestType
const definition = definitions[preferenceId] as unknown as UserPreferenceDefinition<TestType>

return { definition, preferenceId }
}
Loading

0 comments on commit 4838a86

Please sign in to comment.