From 13c70ad214f4391be578278f0674399a9b584501 Mon Sep 17 00:00:00 2001 From: kao Date: Thu, 4 May 2023 10:38:53 -0600 Subject: [PATCH] Add hardwareReportLink for organizations --- src/__tests__/organizations.ts | 16 +++++++++++++--- src/db/OrganizationSchema.ts | 1 + src/db/OrganizationTypes.ts | 5 +++++ src/graphql/schema/Organization.gql | 1 + src/graphql/schema/OrganizationEdit.gql | 2 ++ src/model/MutableOrganizationDataSource.ts | 3 ++- .../__tests__/MutableOrganizationDataSource.ts | 3 +++ src/utils/helpers.ts | 14 ++------------ 8 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/__tests__/organizations.ts b/src/__tests__/organizations.ts index b4852e80..b361fad5 100644 --- a/src/__tests__/organizations.ts +++ b/src/__tests__/organizations.ts @@ -7,7 +7,8 @@ import { AreaType } from '../db/AreaTypes.js' import { OrgType, OrganizationType, OperationType, OrganizationEditableFieldsType } from '../db/OrganizationTypes.js' import { changelogDataSource } from '../model/ChangeLogDataSource.js' import { queryAPI, setUpServer } from '../utils/testUtils.js' -import { muuidToString, isMuuidHexStr } from '../utils/helpers.js' +import { muuidToString } from '../utils/helpers.js' +import { validate as validateMuuid } from 'uuid' jest.setTimeout(60000) @@ -72,6 +73,8 @@ describe('organizations API', () => { email donationLink instagramLink + facebookLink + hardwareReportLink description } } @@ -90,7 +93,7 @@ describe('organizations API', () => { expect(createResponse.statusCode).toBe(200) const orgId = createResponse.body.data.organization.orgId // orgId is MUUID scalar type which should always be serialized into the muuid hex string format. - expect(isMuuidHexStr(orgId)).toBeTruthy() + expect(validateMuuid(orgId)).toBeTruthy() expect(createResponse.body.data.organization.orgType).toBe('LOCAL_CLIMBING_ORGANIZATION') expect(createResponse.body.data.organization.displayName).toBe('Friends of Openbeta') expect(createResponse.body.data.organization.associatedAreaIds).toStrictEqual([]) @@ -111,6 +114,8 @@ describe('organizations API', () => { email: 'admin@alliesofopenbeta.com', donationLink: 'https://donate.alliesofopenbeta.com', instagramLink: 'https://instagram.com/alliesofopenbeta', + facebookLink: 'https://www.facebook.com/alliesofopenbeta', + hardwareReportLink: 'https://www.alliesofopenbeta.com/reporthardware', description: 'We are allies of OpenBeta!' } }, @@ -128,6 +133,8 @@ describe('organizations API', () => { expect(orgResult.content.email).toBe('admin@alliesofopenbeta.com') expect(orgResult.content.donationLink).toBe('https://donate.alliesofopenbeta.com') expect(orgResult.content.instagramLink).toBe('https://instagram.com/alliesofopenbeta') + expect(orgResult.content.facebookLink).toBe('https://www.facebook.com/alliesofopenbeta') + expect(orgResult.content.hardwareReportLink).toBe('https://www.alliesofopenbeta.com/reporthardware') expect(orgResult.content.description).toBe('We are allies of OpenBeta!') // eslint-disable-next-line @@ -180,6 +187,7 @@ describe('organizations API', () => { donationLink instagramLink facebookLink + hardwareReportLink description } } @@ -207,7 +215,8 @@ describe('organizations API', () => { associatedAreaIds: [ca.metadata.area_id, wa.metadata.area_id], email: 'admin@alphaopenbeta.com', facebookLink: 'https://www.facebook.com/alphaopenbeta', - instagramLink: 'https://www.instagram.com/alphaopenbeta' + instagramLink: 'https://www.instagram.com/alphaopenbeta', + hardwareReportLink: 'https://alphaopenbeta.com/reporthardware' } alphaOrg = await organizations.addOrganization(user, OrgType.localClimbingOrganization, alphaFields) .then((res: OrganizationType | null) => { @@ -251,6 +260,7 @@ describe('organizations API', () => { expect(orgResult.content.email).toBe(alphaFields.email) expect(orgResult.content.instagramLink).toBe(alphaFields.instagramLink) expect(orgResult.content.facebookLink).toBe(alphaFields.facebookLink) + expect(orgResult.content.hardwareReportLink).toBe(alphaFields.hardwareReportLink) }) it('retrieves organizations using an exactMatch displayName filter', async () => { diff --git a/src/db/OrganizationSchema.ts b/src/db/OrganizationSchema.ts index f8c4720f..be95caa2 100644 --- a/src/db/OrganizationSchema.ts +++ b/src/db/OrganizationSchema.ts @@ -27,6 +27,7 @@ const ContentSchema = new Schema({ donationLink: { type: Schema.Types.String }, instagramLink: { type: Schema.Types.String }, facebookLink: { type: Schema.Types.String }, + hardwareReportLink: { type: Schema.Types.String }, description: { type: Schema.Types.String } }, { _id: false }) diff --git a/src/db/OrganizationTypes.ts b/src/db/OrganizationTypes.ts index c565f4a3..84a7b899 100644 --- a/src/db/OrganizationTypes.ts +++ b/src/db/OrganizationTypes.ts @@ -82,6 +82,10 @@ export interface IOrganizationContent { * URL of organization's Facebook page. */ facebookLink?: string + /** + * URL of where climbers can report bad hardware to the organization. + */ + hardwareReportLink?: string /** longform to mediumform description of this organization. * * We expect org_admins to make a call about whatever kind of context may be appropriate @@ -101,6 +105,7 @@ export interface OrganizationEditableFieldsType { donationLink?: string instagramLink?: string facebookLink?: string + hardwareReportLink?: string description?: string } diff --git a/src/graphql/schema/Organization.gql b/src/graphql/schema/Organization.gql index 1f4f72de..edc8a19d 100644 --- a/src/graphql/schema/Organization.gql +++ b/src/graphql/schema/Organization.gql @@ -34,6 +34,7 @@ type OrganizationContent { donationLink: String instagramLink: String facebookLink: String + hardwareReportLink: String description: String } diff --git a/src/graphql/schema/OrganizationEdit.gql b/src/graphql/schema/OrganizationEdit.gql index b7149c90..e6cd125b 100644 --- a/src/graphql/schema/OrganizationEdit.gql +++ b/src/graphql/schema/OrganizationEdit.gql @@ -20,6 +20,7 @@ input AddOrganizationInput { donationLink: String instagramLink: String facebookLink: String + hardwareReportLink: String description: String } @@ -33,5 +34,6 @@ input OrganizationEditableFieldsInput { donationLink: String instagramLink: String facebookLink: String + hardwareReportLink: String description: String } diff --git a/src/model/MutableOrganizationDataSource.ts b/src/model/MutableOrganizationDataSource.ts index d7bae06a..45ce001d 100644 --- a/src/model/MutableOrganizationDataSource.ts +++ b/src/model/MutableOrganizationDataSource.ts @@ -135,7 +135,7 @@ const findNonexistantAreas = async (areaIds: MUUID[]): Promise => { const sanitizeEditableFields = async ( document: OrganizationEditableFieldsType ): Promise> => { - const { associatedAreaIds, excludedAreaIds, displayName, website, email, donationLink, instagramLink, facebookLink, description } = document + const { associatedAreaIds, excludedAreaIds, displayName, website, email, donationLink, instagramLink, facebookLink, hardwareReportLink, description } = document const orgFragment: Partial = {} if (associatedAreaIds !== undefined && associatedAreaIds.length > 0) { @@ -154,6 +154,7 @@ const sanitizeEditableFields = async ( if (donationLink !== undefined) { orgFragment['content.donationLink'] = sanitizeStrict(donationLink) } if (instagramLink !== undefined) { orgFragment['content.instagramLink'] = sanitizeStrict(instagramLink) } if (facebookLink !== undefined) { orgFragment['content.facebookLink'] = sanitizeStrict(facebookLink) } + if (hardwareReportLink !== undefined) { orgFragment['content.hardwareReportLink'] = sanitizeStrict(hardwareReportLink) } if (description !== undefined) { orgFragment['content.description'] = sanitize(description) } return orgFragment diff --git a/src/model/__tests__/MutableOrganizationDataSource.ts b/src/model/__tests__/MutableOrganizationDataSource.ts index f2421cc2..5be564c1 100644 --- a/src/model/__tests__/MutableOrganizationDataSource.ts +++ b/src/model/__tests__/MutableOrganizationDataSource.ts @@ -39,6 +39,7 @@ describe('Organization', () => { donationLink: 'https://www.friendsofopenbeta.com/donate', instagramLink: 'https://www.instagram.com/friendsofopenbeta', facebookLink: 'https://www.facebook.com/friendsofopenbeta', + hardwareReportLink: 'https://www.friendsofopenbeta.com/reporthardware', description: 'We are friends of openbeta.\nWe are a 503(B) corporation.' } emptyOrg = { @@ -68,6 +69,7 @@ describe('Organization', () => { expect(newOrg.content?.donationLink).toBe(document.donationLink) expect(newOrg.content?.instagramLink).toBe(document.instagramLink) expect(newOrg.content?.facebookLink).toBe(document.facebookLink) + expect(newOrg.content?.hardwareReportLink).toBe(document.hardwareReportLink) expect(newOrg.content?.description).toBe(document.description) expect(newOrg.associatedAreaIds.map(muuidToString)).toEqual([muuidToString(usa.metadata.area_id)]) expect(newOrg._change?.operation).toBe('addOrganization') @@ -114,6 +116,7 @@ describe('Organization', () => { expect(updatedOrg.content?.donationLink).toBe(document.donationLink) expect(updatedOrg.content?.instagramLink).toBe(document.instagramLink) expect(updatedOrg.content?.facebookLink).toBe(document.facebookLink) + expect(updatedOrg.content?.hardwareReportLink).toBe(document.hardwareReportLink) expect(updatedOrg.content?.description).toBe(document.description) expect(updatedOrg._change?.operation).toBe('updateOrganization') expect(updatedOrg._change?.seq).toBe(0) diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 0e112bd8..5c7400f8 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -13,23 +13,13 @@ export const isBase64Str = (s: string): boolean => { return bc && lc } -/** - * Detects if string is in uuid-mongodb's "relaxed" hex format. - * @param s input string - * @returns - */ -export const isMuuidHexStr = (s: string): boolean => { - const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ - return regex.test(s) -} - /** * Ensures that type-checking errors out if enums are not - * handlded exhaustively in switch statements. + * handled exhaustively in switch statements. * Eg. * switch(val) { * case enumOne: - * ... + * ... * default: * exhaustiveCheck(val) * }