|
|
@@ -0,0 +1,502 @@
|
|
|
+import { setActivePinia, createPinia } from 'pinia'
|
|
|
+import { beforeEach, describe, it, expect, vi } from 'vitest'
|
|
|
+import { useUserStore } from '../../stores/user'
|
|
|
+import { authApi, profileApi } from '../../utils/api'
|
|
|
+
|
|
|
+// ── Mock API module ──────────────────────────────────────────────
|
|
|
+// vi.mock is hoisted to the top of the file, before any imports.
|
|
|
+vi.mock('../../utils/api', () => ({
|
|
|
+ authApi: {
|
|
|
+ login: vi.fn(),
|
|
|
+ },
|
|
|
+ profileApi: {
|
|
|
+ info: vi.fn(),
|
|
|
+ quota: vi.fn(),
|
|
|
+ commissionSummary: vi.fn(),
|
|
|
+ },
|
|
|
+}))
|
|
|
+
|
|
|
+describe('user store', () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ setActivePinia(createPinia())
|
|
|
+ // Reset API mocks between tests so return values don't leak
|
|
|
+ authApi.login.mockReset()
|
|
|
+ profileApi.info.mockReset()
|
|
|
+ profileApi.quota.mockReset()
|
|
|
+ profileApi.commissionSummary.mockReset()
|
|
|
+ })
|
|
|
+
|
|
|
+ // ── Initial state ──────────────────────────────────────────────
|
|
|
+
|
|
|
+ describe('initial state', () => {
|
|
|
+ it('creates with empty token and isLoggedIn=false when no saved token', () => {
|
|
|
+ const store = useUserStore()
|
|
|
+ expect(store.token).toBe('')
|
|
|
+ expect(store.isLoggedIn).toBe(false)
|
|
|
+ expect(store.nickname).toBe('')
|
|
|
+ expect(store.avatarUrl).toBe('')
|
|
|
+ expect(store.isVip).toBe(false)
|
|
|
+ expect(store.vipType).toBeNull()
|
|
|
+ expect(store.vipEndTime).toBeNull()
|
|
|
+ expect(store.referralCode).toBe('')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('loads token from storage and sets isLoggedIn=true', () => {
|
|
|
+ uni.__mockStorage.token = 'saved-token-abc'
|
|
|
+ const store = useUserStore()
|
|
|
+ expect(store.token).toBe('saved-token-abc')
|
|
|
+ expect(store.isLoggedIn).toBe(true)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('loads empty string when storage returns falsy', () => {
|
|
|
+ uni.__mockStorage.token = ''
|
|
|
+ const store = useUserStore()
|
|
|
+ expect(store.token).toBe('')
|
|
|
+ expect(store.isLoggedIn).toBe(false)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // ── login() ────────────────────────────────────────────────────
|
|
|
+
|
|
|
+ describe('login()', () => {
|
|
|
+ it('calls authApi.login with openid, nickname, avatarUrl', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 'new-token', profileIncomplete: false })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.login('openid-123', 'Alice', 'http://avatar.url/1', 'ref-999')
|
|
|
+
|
|
|
+ expect(authApi.login).toHaveBeenCalledWith({
|
|
|
+ openid: 'openid-123',
|
|
|
+ nickname: 'Alice',
|
|
|
+ avatarUrl: 'http://avatar.url/1',
|
|
|
+ referralCode: 'ref-999',
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('calls authApi.login without referralCode when not provided', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 'new-token', profileIncomplete: false })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.login('openid-123', 'Alice', 'http://avatar.url/1', '')
|
|
|
+
|
|
|
+ expect(authApi.login).toHaveBeenCalledWith({
|
|
|
+ openid: 'openid-123',
|
|
|
+ nickname: 'Alice',
|
|
|
+ avatarUrl: 'http://avatar.url/1',
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('sets token, nickname, avatarUrl from login response', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 'jwt-token-abc', profileIncomplete: false })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.login('oid', 'Bob', 'http://avatar/bob', '')
|
|
|
+
|
|
|
+ expect(store.token).toBe('jwt-token-abc')
|
|
|
+ expect(store.nickname).toBe('Bob')
|
|
|
+ expect(store.avatarUrl).toBe('http://avatar/bob')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('persists token to storage', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 'persisted-token', profileIncomplete: false })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.login('oid', 'Bob', '', '')
|
|
|
+
|
|
|
+ expect(uni.setStorageSync).toHaveBeenCalledWith('token', 'persisted-token')
|
|
|
+ expect(uni.__mockStorage.token).toBe('persisted-token')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('handles res being a raw string (no .token wrapper)', async () => {
|
|
|
+ authApi.login.mockResolvedValue('raw-string-token')
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.login('oid', 'Bob', '', '')
|
|
|
+
|
|
|
+ expect(store.token).toBe('raw-string-token')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('sets profileIncomplete from response', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 't', profileIncomplete: true })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.login('oid', 'Bob', '', '')
|
|
|
+
|
|
|
+ expect(store.profileIncomplete).toBe(true)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // ── wechatLogin() ──────────────────────────────────────────────
|
|
|
+
|
|
|
+ describe('wechatLogin()', () => {
|
|
|
+ it('calls authApi.login with code instead of openid', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 'wx-token', profileIncomplete: false })
|
|
|
+ profileApi.info.mockResolvedValue({ nickname: 'wxuser', avatarUrl: '' })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.wechatLogin('code-abc', 'WeChatUser', 'http://avatar', 'ref')
|
|
|
+
|
|
|
+ expect(authApi.login).toHaveBeenCalledWith({
|
|
|
+ code: 'code-abc',
|
|
|
+ nickname: 'WeChatUser',
|
|
|
+ avatarUrl: 'http://avatar',
|
|
|
+ referralCode: 'ref',
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it('falls back to default nickname when empty (before fetchProfile completes)', async () => {
|
|
|
+ // The store sets nickname || '微信用户' before calling fetchProfile.
|
|
|
+ // However, fetchProfile always overwrites it with the API value (even undefined).
|
|
|
+ // This test verifies the code path exists and no error is thrown.
|
|
|
+ authApi.login.mockResolvedValue({ token: 'wx-token', profileIncomplete: false })
|
|
|
+ profileApi.info.mockResolvedValue({ nickname: 'ServerName', avatarUrl: '' })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.wechatLogin('code-abc', '', '', '')
|
|
|
+
|
|
|
+ // fetchProfile response takes precedence over the temporary fallback
|
|
|
+ expect(store.nickname).toBe('ServerName')
|
|
|
+ expect(store.avatarUrl).toBe('')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('fetches full profile after login', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 'wx-token', profileIncomplete: false })
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ nickname: 'ServerNick',
|
|
|
+ avatarUrl: 'http://server/avatar',
|
|
|
+ referralCode: 'CODE123',
|
|
|
+ vipType: 'year',
|
|
|
+ vipEndTime: '2027-06-08T00:00:00',
|
|
|
+ gender: 1,
|
|
|
+ birthDate: '1990-01-15',
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.wechatLogin('code-abc', 'WeChatUser', 'http://avatar', '')
|
|
|
+
|
|
|
+ // Token set from login
|
|
|
+ expect(store.token).toBe('wx-token')
|
|
|
+ // Profile loaded from API
|
|
|
+ expect(store.nickname).toBe('ServerNick')
|
|
|
+ expect(store.referralCode).toBe('CODE123')
|
|
|
+ expect(store.vipType).toBe('year')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('does not throw when fetchProfile fails', async () => {
|
|
|
+ authApi.login.mockResolvedValue({ token: 'wx-token', profileIncomplete: false })
|
|
|
+ profileApi.info.mockRejectedValue(new Error('network error'))
|
|
|
+ const store = useUserStore()
|
|
|
+
|
|
|
+ await expect(store.wechatLogin('code', 'name', '', '')).resolves.not.toThrow()
|
|
|
+ expect(store.token).toBe('wx-token')
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // ── fetchProfile() ─────────────────────────────────────────────
|
|
|
+
|
|
|
+ describe('fetchProfile()', () => {
|
|
|
+ const mockProfile = {
|
|
|
+ nickname: 'TestUser',
|
|
|
+ avatarUrl: 'http://avatar/test',
|
|
|
+ referralCode: 'REF123',
|
|
|
+ vipType: 'month',
|
|
|
+ vipEndTime: '2026-12-31T23:59:59',
|
|
|
+ gender: 1,
|
|
|
+ birthDate: '1990-06-15',
|
|
|
+ bio: 'Hello world',
|
|
|
+ city: 'Shanghai',
|
|
|
+ tags: 'reader,traveler',
|
|
|
+ lookingFor: 2,
|
|
|
+ profileComplete: true,
|
|
|
+ birthYear: 1990,
|
|
|
+ birthMonth: 6,
|
|
|
+ birthDay: 15,
|
|
|
+ }
|
|
|
+
|
|
|
+ it('updates all user fields from API response', async () => {
|
|
|
+ profileApi.info.mockResolvedValue(mockProfile)
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.nickname).toBe('TestUser')
|
|
|
+ expect(store.avatarUrl).toBe('http://avatar/test')
|
|
|
+ expect(store.referralCode).toBe('REF123')
|
|
|
+ expect(store.vipType).toBe('month')
|
|
|
+ expect(store.vipEndTime).toBe('2026-12-31T23:59:59')
|
|
|
+ expect(store.gender).toBe(1)
|
|
|
+ expect(store.birthDate).toBe('1990-06-15')
|
|
|
+ expect(store.bio).toBe('Hello world')
|
|
|
+ expect(store.city).toBe('Shanghai')
|
|
|
+ expect(store.tags).toBe('reader,traveler')
|
|
|
+ expect(store.lookingFor).toBe(2)
|
|
|
+ expect(store.profileComplete).toBe(true)
|
|
|
+ expect(store.birthYear).toBe(1990)
|
|
|
+ expect(store.birthMonth).toBe(6)
|
|
|
+ expect(store.birthDay).toBe(15)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('normalizes vipEndTime from Jackson array [y,m,d,h,m,s] to ISO string', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ ...mockProfile,
|
|
|
+ vipEndTime: [2026, 6, 8, 23, 59, 59],
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.vipEndTime).toBe('2026-06-08T23:59:59')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('normalizes vipEndTime with single-digit month/day padding', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ ...mockProfile,
|
|
|
+ vipEndTime: [2026, 1, 5, 9, 5, 3],
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.vipEndTime).toBe('2026-01-05T09:05:03')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('handles null vipEndTime', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ ...mockProfile,
|
|
|
+ vipEndTime: null,
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.vipEndTime).toBeNull()
|
|
|
+ expect(store.isVip).toBe(false)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('handles undefined vipEndTime', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ ...mockProfile,
|
|
|
+ vipEndTime: undefined,
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.vipEndTime).toBeNull()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('sets isVip=true when vipEndTime is in the future', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ ...mockProfile,
|
|
|
+ vipEndTime: '2099-01-01T00:00:00', // far future
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.isVip).toBe(true)
|
|
|
+ expect(store.isVipActive).toBe(true)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('sets isVip=false when vipEndTime is in the past', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ ...mockProfile,
|
|
|
+ vipEndTime: '2020-01-01T00:00:00', // past
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.isVip).toBe(false)
|
|
|
+ // isVipActive getter computes from vipEndTime
|
|
|
+ expect(store.isVipActive).toBe(false)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('handles missing optional fields with defaults', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ nickname: 'Minimal',
|
|
|
+ avatarUrl: '',
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ // referralCode is set directly (no || fallback), so stays undefined
|
|
|
+ expect(store.referralCode).toBeUndefined()
|
|
|
+ expect(store.vipType).toBeNull()
|
|
|
+ expect(store.vipEndTime).toBeNull()
|
|
|
+ expect(store.gender).toBe(0)
|
|
|
+ expect(store.birthDate).toBeNull()
|
|
|
+ expect(store.bio).toBe('')
|
|
|
+ expect(store.city).toBe('')
|
|
|
+ expect(store.tags).toBe('')
|
|
|
+ expect(store.lookingFor).toBe(0)
|
|
|
+ expect(store.profileComplete).toBe(false)
|
|
|
+ expect(store.birthYear).toBe(0)
|
|
|
+ expect(store.birthMonth).toBe(0)
|
|
|
+ expect(store.birthDay).toBe(0)
|
|
|
+ expect(store.profileIncomplete).toBe(true)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('sets profileIncomplete to true when profileComplete is falsy', async () => {
|
|
|
+ profileApi.info.mockResolvedValue({
|
|
|
+ nickname: 'Test',
|
|
|
+ avatarUrl: '',
|
|
|
+ profileComplete: false,
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchProfile()
|
|
|
+
|
|
|
+ expect(store.profileIncomplete).toBe(true)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // ── fetchQuota() ───────────────────────────────────────────────
|
|
|
+
|
|
|
+ describe('fetchQuota()', () => {
|
|
|
+ const mockQuota = {
|
|
|
+ dailyChartCount: 2,
|
|
|
+ chartLimit: 10,
|
|
|
+ dailyChatCount: 5,
|
|
|
+ chatLimit: 20,
|
|
|
+ dailyShareCount: 3,
|
|
|
+ shareLimit: 5,
|
|
|
+ dailyAcademicCount: 0,
|
|
|
+ academicLimit: 2,
|
|
|
+ }
|
|
|
+
|
|
|
+ it('updates quota limits from API response', async () => {
|
|
|
+ profileApi.quota.mockResolvedValue(mockQuota)
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchQuota()
|
|
|
+
|
|
|
+ expect(store.usedCharts).toBe(2)
|
|
|
+ expect(store.maxCharts).toBe(10)
|
|
|
+ expect(store.usedChats).toBe(5)
|
|
|
+ expect(store.maxChats).toBe(20)
|
|
|
+ expect(store.shareCount).toBe(3)
|
|
|
+ expect(store.shareLimit).toBe(5)
|
|
|
+ expect(store.usedAcademic).toBe(0)
|
|
|
+ expect(store.maxAcademic).toBe(2)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('falls back to 999 when chart/chats limits are 0 or negative', async () => {
|
|
|
+ profileApi.quota.mockResolvedValue({
|
|
|
+ dailyChartCount: 0,
|
|
|
+ chartLimit: 0,
|
|
|
+ dailyChatCount: 0,
|
|
|
+ chatLimit: 0,
|
|
|
+ dailyShareCount: 0,
|
|
|
+ shareLimit: 0,
|
|
|
+ dailyAcademicCount: 0,
|
|
|
+ academicLimit: 0,
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchQuota()
|
|
|
+
|
|
|
+ expect(store.maxCharts).toBe(999)
|
|
|
+ expect(store.maxChats).toBe(999)
|
|
|
+ expect(store.shareLimit).toBe(1) // defaults to 1 when 0 or negative
|
|
|
+ expect(store.maxAcademic).toBe(1) // defaults to 1 when 0 or negative
|
|
|
+ })
|
|
|
+
|
|
|
+ it('does not throw on API failure (silent catch)', async () => {
|
|
|
+ profileApi.quota.mockRejectedValue(new Error('server error'))
|
|
|
+ const store = useUserStore()
|
|
|
+
|
|
|
+ await expect(store.fetchQuota()).resolves.not.toThrow()
|
|
|
+ // Default values remain
|
|
|
+ expect(store.usedCharts).toBe(0)
|
|
|
+ expect(store.maxCharts).toBe(3)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // ── fetchCommissionSummary() ───────────────────────────────────
|
|
|
+
|
|
|
+ describe('fetchCommissionSummary()', () => {
|
|
|
+ it('updates commission from API response', async () => {
|
|
|
+ profileApi.commissionSummary.mockResolvedValue({
|
|
|
+ totalEarnings: 1500,
|
|
|
+ availableBalance: 800,
|
|
|
+ })
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchCommissionSummary()
|
|
|
+
|
|
|
+ expect(store.totalCommission).toBe(1500)
|
|
|
+ expect(store.availableCommission).toBe(800)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('does not throw on API failure (silent catch)', async () => {
|
|
|
+ profileApi.commissionSummary.mockRejectedValue(new Error('error'))
|
|
|
+ const store = useUserStore()
|
|
|
+
|
|
|
+ await expect(store.fetchCommissionSummary()).resolves.not.toThrow()
|
|
|
+ expect(store.totalCommission).toBe(0)
|
|
|
+ expect(store.availableCommission).toBe(0)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('handles missing response fields', async () => {
|
|
|
+ profileApi.commissionSummary.mockResolvedValue({})
|
|
|
+ const store = useUserStore()
|
|
|
+ await store.fetchCommissionSummary()
|
|
|
+
|
|
|
+ expect(store.totalCommission).toBe(0)
|
|
|
+ expect(store.availableCommission).toBe(0)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // ── logout() ───────────────────────────────────────────────────
|
|
|
+
|
|
|
+ describe('logout()', () => {
|
|
|
+ it('clears token, sets isLoggedIn=false', () => {
|
|
|
+ const store = useUserStore()
|
|
|
+ store.token = 'some-token'
|
|
|
+ store.logout()
|
|
|
+
|
|
|
+ expect(store.token).toBe('')
|
|
|
+ expect(store.isLoggedIn).toBe(false)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('removes token from storage', () => {
|
|
|
+ uni.__mockStorage.token = 'some-token'
|
|
|
+ const store = useUserStore()
|
|
|
+ store.logout()
|
|
|
+
|
|
|
+ expect(uni.removeStorageSync).toHaveBeenCalledWith('token')
|
|
|
+ expect(uni.__mockStorage.token).toBeUndefined()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('resets all state fields to defaults', () => {
|
|
|
+ // Populate with non-default values
|
|
|
+ const store = useUserStore()
|
|
|
+ store.nickname = 'Test'
|
|
|
+ store.avatarUrl = 'http://avatar'
|
|
|
+ store.usedCharts = 5
|
|
|
+ store.usedChats = 10
|
|
|
+ store.usedAcademic = 3
|
|
|
+ store.shareCount = 8
|
|
|
+ store.shareLimit = 20
|
|
|
+ store.maxAcademic = 10
|
|
|
+ store.totalCommission = 500
|
|
|
+ store.availableCommission = 200
|
|
|
+ store.profileIncomplete = true
|
|
|
+ store.gender = 1
|
|
|
+ store.birthDate = '1990-01-01'
|
|
|
+ store.bio = 'bio'
|
|
|
+ store.city = 'city'
|
|
|
+ store.tags = 'tag1,tag2'
|
|
|
+ store.lookingFor = 2
|
|
|
+ store.profileComplete = true
|
|
|
+ store.birthYear = 1990
|
|
|
+ store.birthMonth = 1
|
|
|
+ store.birthDay = 1
|
|
|
+
|
|
|
+ store.logout()
|
|
|
+
|
|
|
+ expect(store.nickname).toBe('')
|
|
|
+ expect(store.avatarUrl).toBe('')
|
|
|
+ expect(store.usedCharts).toBe(0)
|
|
|
+ expect(store.usedChats).toBe(0)
|
|
|
+ expect(store.usedAcademic).toBe(0)
|
|
|
+ expect(store.shareCount).toBe(0)
|
|
|
+ expect(store.shareLimit).toBe(1)
|
|
|
+ expect(store.maxAcademic).toBe(1)
|
|
|
+ expect(store.totalCommission).toBe(0)
|
|
|
+ expect(store.availableCommission).toBe(0)
|
|
|
+ expect(store.profileIncomplete).toBe(false)
|
|
|
+ expect(store.gender).toBe(0)
|
|
|
+ expect(store.birthDate).toBeNull()
|
|
|
+ expect(store.bio).toBe('')
|
|
|
+ expect(store.city).toBe('')
|
|
|
+ expect(store.tags).toBe('')
|
|
|
+ expect(store.lookingFor).toBe(0)
|
|
|
+ expect(store.profileComplete).toBe(false)
|
|
|
+ expect(store.birthYear).toBe(0)
|
|
|
+ expect(store.birthMonth).toBe(0)
|
|
|
+ expect(store.birthDay).toBe(0)
|
|
|
+ })
|
|
|
+ })
|
|
|
+})
|