Skip to content

Commit c9ac31a

Browse files
committed
Add missing ThemeManager tests
1 parent 0ee1d0c commit c9ac31a

1 file changed

Lines changed: 199 additions & 0 deletions

File tree

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import {ThemeManager} from './theme-manager.js'
2+
import {Theme} from './types.js'
3+
import {fetchTheme, themeCreate} from './api.js'
4+
import {DEVELOPMENT_THEME_ROLE, UNPUBLISHED_THEME_ROLE} from './utils.js'
5+
import {BugError} from '../error.js'
6+
import {test, describe, expect, vi, beforeEach} from 'vitest'
7+
8+
vi.mock('./api.js')
9+
vi.mock('../../../private/node/themes/generate-theme-name.js', () => ({
10+
generateThemeName: vi.fn((context: string) => `${context} (test-123-hostname)`),
11+
}))
12+
13+
const session = {token: 'token', storeFqdn: 'my-shop.myshopify.com', refresh: async () => {}}
14+
15+
class TestThemeManager extends ThemeManager {
16+
protected context = 'test-context'
17+
private storedThemeId: string | undefined
18+
19+
constructor(adminSession: any) {
20+
super(adminSession)
21+
this.storedThemeId = undefined
22+
}
23+
24+
getStoredThemeId(): string | undefined {
25+
return this.storedThemeId
26+
}
27+
28+
setThemeId(themeId: string | undefined): void {
29+
this.themeId = themeId
30+
}
31+
32+
protected setTheme(themeId: string): void {
33+
this.storedThemeId = themeId
34+
this.themeId = themeId
35+
}
36+
37+
protected removeTheme(): void {
38+
this.storedThemeId = undefined
39+
this.themeId = undefined
40+
}
41+
}
42+
43+
const mockTheme: Theme = {
44+
id: 123,
45+
name: 'Test Theme',
46+
role: DEVELOPMENT_THEME_ROLE,
47+
processing: false,
48+
createdAtRuntime: false,
49+
}
50+
51+
describe('ThemeManager', () => {
52+
let manager: TestThemeManager
53+
54+
beforeEach(() => {
55+
manager = new TestThemeManager(session)
56+
})
57+
58+
describe('findOrCreate', () => {
59+
test('returns an existing theme when one exists', async () => {
60+
// Given
61+
manager.setThemeId('123')
62+
vi.mocked(fetchTheme).mockResolvedValue(mockTheme)
63+
64+
// When
65+
const result = await manager.findOrCreate()
66+
67+
// Then
68+
expect(fetchTheme).toHaveBeenCalledWith(123, session)
69+
expect(result).toEqual(mockTheme)
70+
expect(themeCreate).not.toHaveBeenCalled()
71+
})
72+
73+
test('creates a new theme when one does not exist', async () => {
74+
// Given
75+
manager.setThemeId(undefined)
76+
vi.mocked(themeCreate).mockResolvedValue(mockTheme)
77+
78+
expect(manager.getStoredThemeId()).toBeUndefined()
79+
80+
// When
81+
const result = await manager.findOrCreate()
82+
83+
// Then
84+
expect(fetchTheme).not.toHaveBeenCalled()
85+
expect(themeCreate).toHaveBeenCalledWith(
86+
{
87+
name: 'test-context (test-123-hostname)',
88+
role: DEVELOPMENT_THEME_ROLE,
89+
},
90+
session,
91+
)
92+
expect(result).toEqual(mockTheme)
93+
expect(manager.getStoredThemeId()).toBe('123')
94+
})
95+
})
96+
97+
describe('fetch', () => {
98+
test('returns undefined when no themeId is set', async () => {
99+
// Given
100+
manager.setThemeId(undefined)
101+
102+
// When
103+
const result = await manager.fetch()
104+
105+
// Then
106+
expect(result).toBeUndefined()
107+
expect(fetchTheme).not.toHaveBeenCalled()
108+
})
109+
110+
test('fetches and returns a theme when themeId is set', async () => {
111+
// Given
112+
manager.setThemeId('123')
113+
vi.mocked(fetchTheme).mockResolvedValue(mockTheme)
114+
115+
// When
116+
const result = await manager.fetch()
117+
118+
// Then
119+
expect(fetchTheme).toHaveBeenCalledWith(123, session)
120+
expect(result).toEqual(mockTheme)
121+
})
122+
123+
test('removes theme when fetch returns undefined', async () => {
124+
// Given
125+
manager.setThemeId('123')
126+
vi.mocked(fetchTheme).mockResolvedValue(undefined)
127+
128+
// When
129+
const result = await manager.fetch()
130+
131+
// Then
132+
expect(fetchTheme).toHaveBeenCalledWith(123, session)
133+
expect(result).toBeUndefined()
134+
expect(manager.getStoredThemeId()).toBeUndefined()
135+
})
136+
})
137+
138+
describe('generateThemeName', () => {
139+
test('generates a theme name with the provided context', () => {
140+
// When
141+
const result = manager.generateThemeName('my-app')
142+
143+
// Then
144+
expect(result).toBe('my-app (test-123-hostname)')
145+
})
146+
})
147+
148+
describe('create', () => {
149+
test('creates a new theme with default role and generated name', async () => {
150+
// Given
151+
vi.mocked(themeCreate).mockResolvedValue(mockTheme)
152+
153+
// When
154+
const result = await manager.create()
155+
156+
// Then
157+
expect(themeCreate).toHaveBeenCalledWith(
158+
{
159+
name: 'test-context (test-123-hostname)',
160+
role: DEVELOPMENT_THEME_ROLE,
161+
},
162+
session,
163+
)
164+
expect(result).toEqual(mockTheme)
165+
expect(manager.getStoredThemeId()).toBe('123')
166+
})
167+
168+
test('creates a new theme with specified role and name', async () => {
169+
// Given
170+
const customTheme = {...mockTheme, name: 'Custom name', role: UNPUBLISHED_THEME_ROLE}
171+
vi.mocked(themeCreate).mockResolvedValue(customTheme)
172+
173+
// When
174+
const result = await manager.create(UNPUBLISHED_THEME_ROLE, 'Custom name')
175+
176+
// Then
177+
expect(themeCreate).toHaveBeenCalledWith(
178+
{
179+
name: 'Custom name',
180+
role: UNPUBLISHED_THEME_ROLE,
181+
},
182+
session,
183+
)
184+
expect(result).toEqual(customTheme)
185+
expect(manager.getStoredThemeId()).toBe('123')
186+
})
187+
188+
test('throws BugError when theme creation fails', async () => {
189+
// Given
190+
vi.mocked(themeCreate).mockResolvedValue(undefined)
191+
192+
// When/Then
193+
await expect(manager.create()).rejects.toThrow(BugError)
194+
await expect(manager.create()).rejects.toThrow(
195+
'Could not create theme with name "test-context (test-123-hostname)" and role "development"',
196+
)
197+
})
198+
})
199+
})

0 commit comments

Comments
 (0)