import * as profilesModule from 'api/get-profiles' import {Profile} from 'common/profiles/profile' import * as supabaseInit from 'shared/supabase/init' import * as sqlBuilder from 'shared/supabase/sql-builder' describe('getProfiles', () => { beforeEach(() => { jest.clearAllMocks() }) afterEach(() => { jest.restoreAllMocks() }) describe('when given valid input', () => { it('should successfully return profile information and count', async () => { const mockProfiles = [ { diet: ['Jonathon Hammon'], has_kids: 0, }, { diet: ['Joseph Hammon'], has_kids: 1, }, { diet: ['Jolene Hammon'], has_kids: 2, }, ] as Profile[] const props = { limit: 2, orderBy: 'last_online_time' as const, } const mockReq = {} as any jest .spyOn(profilesModule, 'loadProfiles') .mockResolvedValue({profiles: mockProfiles, count: 3}) const results: any = await profilesModule.getProfiles(props, mockReq, mockReq) expect(results.status).toEqual('success') expect(results.profiles).toEqual(mockProfiles) expect(results.profiles[0]).toEqual(mockProfiles[0]) expect(profilesModule.loadProfiles).toHaveBeenCalledWith(props) expect(profilesModule.loadProfiles).toHaveBeenCalledTimes(1) }) }) describe('when an error occurs', () => { it('should not return profile information', async () => { jest.spyOn(profilesModule, 'loadProfiles').mockRejectedValue(null) const props = { limit: 2, orderBy: 'last_online_time' as const, } const mockReq = {} as any const results: any = await profilesModule.getProfiles(props, mockReq, mockReq) expect(results.status).toEqual('fail') expect(results.profiles).toEqual([]) expect(profilesModule.loadProfiles).toHaveBeenCalledWith(props) expect(profilesModule.loadProfiles).toHaveBeenCalledTimes(1) }) }) }) describe('loadProfiles', () => { let mockPg: any beforeEach(() => { jest.clearAllMocks() mockPg = { map: jest.fn(), one: jest.fn(), } jest.spyOn(supabaseInit, 'createSupabaseDirectClient').mockReturnValue(mockPg) }) afterEach(() => { jest.restoreAllMocks() }) describe('when given valid input', () => { describe('should call pg.map with an SQL query', () => { it('successfully', async () => { const mockProps = { limit: 10, name: 'John', is_smoker: true, } ;(mockPg.map as jest.Mock).mockResolvedValue([]) ;(mockPg.one as jest.Mock).mockResolvedValue(1) jest.spyOn(sqlBuilder, 'renderSql') jest.spyOn(sqlBuilder, 'select') jest.spyOn(sqlBuilder, 'from') jest.spyOn(sqlBuilder, 'where') jest.spyOn(sqlBuilder, 'join') await profilesModule.loadProfiles(mockProps) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain('select') expect(query).toContain('from profiles') expect(query).toContain('where') expect(query).toContain('limit 10') expect(query).toContain(`John`) expect(query).toContain(`is_smoker`) expect(query).not.toContain(`gender`) expect(query).not.toContain(`education_level`) expect(query).not.toContain(`pref_gender`) expect(query).not.toContain(`age`) expect(query).not.toContain(`drinks_per_month`) expect(query).not.toContain(`pref_relation_styles`) expect(query).not.toContain(`pref_romantic_styles`) expect(query).not.toContain(`diet`) expect(query).not.toContain(`political_beliefs`) expect(query).not.toContain(`religion`) expect(query).not.toContain(`has_kids`) expect(sqlBuilder.renderSql).toBeCalledTimes(3) expect(sqlBuilder.select).toBeCalledTimes(3) expect(sqlBuilder.from).toBeCalledTimes(2) expect(sqlBuilder.where).toBeCalledTimes(7) expect(sqlBuilder.join).toBeCalledTimes(1) }) it('that contains a gender filter', async () => { await profilesModule.loadProfiles({ genders: ['Electrical_gender'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`gender`) expect(query).toContain(`Electrical_gender`) }) it('that contains a education level filter', async () => { await profilesModule.loadProfiles({ education_levels: ['High School'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`education_level`) expect(query).toContain(`High School`) }) it('that contains a prefer gender filter', async () => { await profilesModule.loadProfiles({ pref_gender: ['female'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] console.log(query) expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`pref_gender`) expect(query).toContain(`female`) }) it('that contains a minimum age filter', async () => { await profilesModule.loadProfiles({ pref_age_min: 20, }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`age`) expect(query).toContain(`>= 20`) }) it('that contains a maximum age filter', async () => { await profilesModule.loadProfiles({ pref_age_max: 40, }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`age`) expect(query).toContain(`<= 40`) }) it('that contains a minimum drinks per month filter', async () => { await profilesModule.loadProfiles({ drinks_min: 4, }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`drinks_per_month`) expect(query).toContain('4') }) it('that contains a maximum drinks per month filter', async () => { await profilesModule.loadProfiles({ drinks_max: 20, }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`drinks_per_month`) expect(query).toContain('20') }) it('that contains a relationship style filter', async () => { await profilesModule.loadProfiles({ pref_relation_styles: ['Chill and relaxing'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`pref_relation_styles`) expect(query).toContain('Chill and relaxing') }) it('that contains a romantic style filter', async () => { await profilesModule.loadProfiles({ pref_romantic_styles: ['Sexy'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`pref_romantic_styles`) expect(query).toContain('Sexy') }) it('that contains a diet filter', async () => { await profilesModule.loadProfiles({ diet: ['Glutton'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`diet`) expect(query).toContain('Glutton') }) it('that contains a political beliefs filter', async () => { await profilesModule.loadProfiles({ political_beliefs: ['For the people'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`political_beliefs`) expect(query).toContain('For the people') }) it('that contains a religion filter', async () => { await profilesModule.loadProfiles({ religion: ['The blood god'], }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`religion`) expect(query).toContain('The blood god') }) it('that contains a has kids filter', async () => { await profilesModule.loadProfiles({ has_kids: 3, }) const [query, _values, _cb] = mockPg.map.mock.calls[0] expect(mockPg.map.mock.calls).toHaveLength(1) expect(query).toContain(`has_kids`) expect(query).toContain('> 0') }) it('should return profiles from the database', async () => { const mockProfiles = [ { diet: ['Jonathon Hammon'], is_smoker: true, has_kids: 0, }, { diet: ['Joseph Hammon'], is_smoker: false, has_kids: 1, }, { diet: ['Jolene Hammon'], is_smoker: true, has_kids: 2, }, ] as Profile[] const props = {} as any ;(mockPg.map as jest.Mock).mockResolvedValue(mockProfiles) ;(mockPg.one as jest.Mock).mockResolvedValue(1) const results = await profilesModule.loadProfiles(props) expect(results).toEqual({profiles: mockProfiles, count: 1}) }) }) }) describe('when an error occurs', () => { it('throw if there is no compatability', async () => { const props = { orderBy: 'compatibility_score', } expect(profilesModule.loadProfiles(props)).rejects.toThrowError('Incompatible with user ID') }) }) })