Add member address, state normalization, account inheritance, fix member form
- Address field on member table (jsonb, same format as account) - Members inherit email, phone, address from account when not provided - State normalization: "Texas" → "TX", "california" → "CA" via shared util - Member form drops zodResolver to fix optional field validation flashing - Account name auto-format: "First Last - Account" - US state lookup with full name + code support
This commit is contained in:
@@ -255,4 +255,106 @@ describe('Top-level member routes', () => {
|
||||
expect(res.json().dateOfBirth).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Account inheritance', () => {
|
||||
it('inherits email, phone from account when not provided', async () => {
|
||||
const acctRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/v1/accounts',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { name: 'Email Family', email: 'family@test.com', phone: '555-1234' },
|
||||
})
|
||||
|
||||
const res = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/v1/accounts/${acctRes.json().id}/members`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { firstName: 'Child', lastName: 'One' },
|
||||
})
|
||||
|
||||
expect(res.statusCode).toBe(201)
|
||||
expect(res.json().email).toBe('family@test.com')
|
||||
expect(res.json().phone).toBe('555-1234')
|
||||
})
|
||||
|
||||
it('uses member email when provided instead of account', async () => {
|
||||
const acctRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/v1/accounts',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { name: 'Override Family', email: 'family@test.com' },
|
||||
})
|
||||
|
||||
const res = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/v1/accounts/${acctRes.json().id}/members`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { firstName: 'Adult', lastName: 'Own', email: 'own@test.com' },
|
||||
})
|
||||
|
||||
expect(res.statusCode).toBe(201)
|
||||
expect(res.json().email).toBe('own@test.com')
|
||||
})
|
||||
|
||||
it('inherits address from account when not provided', async () => {
|
||||
const acctRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/v1/accounts',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
name: 'Address Family',
|
||||
address: { street: '123 Main St', city: 'Austin', state: 'TX', zip: '78701' },
|
||||
},
|
||||
})
|
||||
|
||||
const res = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/v1/accounts/${acctRes.json().id}/members`,
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { firstName: 'Kid', lastName: 'Home' },
|
||||
})
|
||||
|
||||
expect(res.statusCode).toBe(201)
|
||||
expect(res.json().address.city).toBe('Austin')
|
||||
expect(res.json().address.state).toBe('TX')
|
||||
})
|
||||
})
|
||||
|
||||
describe('State normalization', () => {
|
||||
it('normalizes state name to code on account', async () => {
|
||||
const res = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/v1/accounts',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { name: 'State Test', address: { state: 'texas' } },
|
||||
})
|
||||
|
||||
expect(res.statusCode).toBe(201)
|
||||
expect(res.json().address.state).toBe('TX')
|
||||
})
|
||||
|
||||
it('normalizes full state name to code', async () => {
|
||||
const res = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/v1/accounts',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { name: 'State Name Test', address: { state: 'California' } },
|
||||
})
|
||||
|
||||
expect(res.statusCode).toBe(201)
|
||||
expect(res.json().address.state).toBe('CA')
|
||||
})
|
||||
|
||||
it('leaves unrecognized state codes as-is', async () => {
|
||||
const res = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/v1/accounts',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: { name: 'Foreign Test', address: { state: 'ON' } },
|
||||
})
|
||||
|
||||
expect(res.statusCode).toBe(201)
|
||||
expect(res.json().address.state).toBe('ON')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user