Slave/blog #9
@@ -13,6 +13,7 @@ import { JwtGuard } from '../../../guards/JwtGuard';
|
||||
import { shopFaviconFilePipe, shopFaviconUploadOptions } from '../config/shopFaviconUpload';
|
||||
import { shopLogoFilePipe, shopLogoUploadOptions } from '../config/shopLogoUpload';
|
||||
import { ConnectSimplexNotificationsDto } from '../dto/ConnectSimplexNotificationsDto';
|
||||
import { UpdateBlogEnabledDto } from '../dto/UpdateBlogEnabledDto';
|
||||
import { UpdateNotificationsDto } from '../dto/UpdateNotificationsDto';
|
||||
import { UpdateShippingNoteDto } from '../dto/UpdateShippingNoteDto';
|
||||
import { UpdateSimplexLinkDto } from '../dto/UpdateSimplexLinkDto';
|
||||
@@ -43,6 +44,11 @@ export class ShopSettingsController {
|
||||
return this.shopSettingsService.updateNotifications(dto);
|
||||
}
|
||||
|
||||
@Patch('/blog-enabled')
|
||||
updateBlogEnabled(@Body() dto: UpdateBlogEnabledDto) {
|
||||
return this.shopSettingsService.updateBlogEnabled(dto);
|
||||
}
|
||||
|
||||
@Post('/simplex-connect')
|
||||
connectSimplexNotifications(@Body() dto: ConnectSimplexNotificationsDto) {
|
||||
return this.shopSettingsService.connectSimplexNotifications(dto.simplexNotificationLink);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { IsBoolean, IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class UpdateBlogEnabledDto {
|
||||
@IsNotEmpty()
|
||||
@IsBoolean()
|
||||
blogEnabled: boolean;
|
||||
}
|
||||
@@ -25,6 +25,7 @@ describe('ShopSettingsService', () => {
|
||||
notifyOnNewOrder: false,
|
||||
notifyOnOrderMessage: false,
|
||||
simplexNotificationContactId: null,
|
||||
blogEnabled: false,
|
||||
createdAt: new Date('2026-01-01T00:00:00.000Z'),
|
||||
updatedAt: new Date('2026-01-01T00:00:00.000Z')
|
||||
} as ShopSettings;
|
||||
@@ -67,10 +68,27 @@ describe('ShopSettingsService', () => {
|
||||
logoUrl: '/uploads/public/shop/logo.png',
|
||||
faviconUrl: null,
|
||||
simplexLink: 'https://simplex.example',
|
||||
shippingNote: 'Ships in 3 days'
|
||||
shippingNote: 'Ships in 3 days',
|
||||
blogEnabled: false
|
||||
});
|
||||
});
|
||||
|
||||
it('updates blog enabled flag', async () => {
|
||||
await service.updateBlogEnabled({ blogEnabled: true });
|
||||
|
||||
expect(shopSettingsRepo.update).toHaveBeenCalledWith('settings-1', { blogEnabled: true });
|
||||
});
|
||||
|
||||
it('includes blog enabled in shop settings view', async () => {
|
||||
shopSettingsRepo.find.mockResolvedValue([{ ...settings, blogEnabled: true }]);
|
||||
|
||||
await expect(service.getView()).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
blogEnabled: true
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('trims simplex links on update', async () => {
|
||||
await service.updateSimplexLink({ simplexLink: ' https://simplex.example/new ' });
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { getShopBrandingPublicUrl, resolveShopBrandingPath } from '../../../conf
|
||||
import { Config } from '../../../types/Config';
|
||||
import { removeFileFromDisk } from '../../../utils/removeFileFromDisk';
|
||||
import { SimplexChatClient } from '../../simplex/services/SimplexChatClient';
|
||||
import { UpdateBlogEnabledDto } from '../dto/UpdateBlogEnabledDto';
|
||||
import { UpdateNotificationsDto } from '../dto/UpdateNotificationsDto';
|
||||
import { UpdateShippingNoteDto } from '../dto/UpdateShippingNoteDto';
|
||||
import { UpdateSimplexLinkDto } from '../dto/UpdateSimplexLinkDto';
|
||||
@@ -43,7 +44,8 @@ export class ShopSettingsService {
|
||||
logoUrl,
|
||||
faviconUrl,
|
||||
simplexLink: settings.simplexLink,
|
||||
shippingNote: settings.shippingNote
|
||||
shippingNote: settings.shippingNote,
|
||||
blogEnabled: settings.blogEnabled
|
||||
};
|
||||
}
|
||||
|
||||
@@ -93,6 +95,14 @@ export class ShopSettingsService {
|
||||
return this.getView();
|
||||
}
|
||||
|
||||
async updateBlogEnabled({ blogEnabled }: UpdateBlogEnabledDto): Promise<ShopSettingsView> {
|
||||
const settings = await this.findSettings();
|
||||
|
||||
await this.shopSettingsRepo.update(settings.id, { blogEnabled });
|
||||
|
||||
return this.getView();
|
||||
}
|
||||
|
||||
async uploadLogo(filename: string): Promise<ShopSettingsView> {
|
||||
const settings = await this.findSettings();
|
||||
|
||||
@@ -191,6 +201,7 @@ export class ShopSettingsService {
|
||||
notifyOnNewOrder,
|
||||
notifyOnOrderMessage,
|
||||
simplexNotificationContactId,
|
||||
blogEnabled,
|
||||
createdAt,
|
||||
updatedAt
|
||||
}: ShopSettings): ShopSettingsView {
|
||||
@@ -220,6 +231,7 @@ export class ShopSettingsService {
|
||||
notifyOnNewOrder,
|
||||
notifyOnOrderMessage,
|
||||
simplexNotificationConnected: simplexNotificationContactId !== null,
|
||||
blogEnabled,
|
||||
isSetupComplete,
|
||||
setupChecklist,
|
||||
createdAt,
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface ShopSettingsView {
|
||||
notifyOnNewOrder: boolean;
|
||||
notifyOnOrderMessage: boolean;
|
||||
simplexNotificationConnected: boolean;
|
||||
blogEnabled: boolean;
|
||||
isSetupComplete: boolean;
|
||||
setupChecklist: SetupChecklist;
|
||||
createdAt: Date | null;
|
||||
|
||||
@@ -3,4 +3,5 @@ export interface StorefrontBranding {
|
||||
faviconUrl: string | null;
|
||||
simplexLink: string | null;
|
||||
shippingNote: string | null;
|
||||
blogEnabled: boolean;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ describe('StorefrontShopViewService', () => {
|
||||
logoUrl: null,
|
||||
faviconUrl: null,
|
||||
simplexLink: null,
|
||||
shippingNote: null
|
||||
shippingNote: null,
|
||||
blogEnabled: false
|
||||
},
|
||||
shopSettings = {
|
||||
shopName: 'Demo Shop',
|
||||
|
||||
@@ -13,6 +13,7 @@ export type StorefrontShopViewServiceOverrides = {
|
||||
faviconUrl: string | null;
|
||||
simplexLink: string | null;
|
||||
shippingNote: string | null;
|
||||
blogEnabled: boolean;
|
||||
};
|
||||
shopSettings?: { shopName: string; shopFiatCurrency: string; enabledPaymentMethods?: PaymentMethod[] };
|
||||
fiatPerXmr?: number;
|
||||
|
||||
Reference in New Issue
Block a user