feat: Add support for exporting products in backend (#8214)
CLOSES CC-221 CLOSES CC-223 CLOSES CC-224
This commit is contained in:
+39
-2
@@ -1,6 +1,16 @@
|
||||
import { INotificationModuleService } from "@medusajs/types"
|
||||
import { Module, Modules } from "@medusajs/utils"
|
||||
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
|
||||
import {
|
||||
CommonEvents,
|
||||
Module,
|
||||
Modules,
|
||||
NotificationEvents,
|
||||
composeMessage,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
MockEventBusService,
|
||||
moduleIntegrationTestRunner,
|
||||
SuiteOptions,
|
||||
} from "medusa-test-utils"
|
||||
import { resolve } from "path"
|
||||
import { NotificationModuleService } from "@services"
|
||||
|
||||
@@ -27,6 +37,12 @@ moduleIntegrationTestRunner({
|
||||
moduleOptions,
|
||||
testSuite: ({ service }: SuiteOptions<INotificationModuleService>) =>
|
||||
describe("Notification Module Service", () => {
|
||||
let eventBusEmitSpy
|
||||
|
||||
beforeEach(() => {
|
||||
eventBusEmitSpy = jest.spyOn(MockEventBusService.prototype, "emit")
|
||||
})
|
||||
|
||||
it(`should export the appropriate linkable configuration`, () => {
|
||||
const linkable = Module(Modules.NOTIFICATION, {
|
||||
service: NotificationModuleService,
|
||||
@@ -67,6 +83,27 @@ moduleIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
|
||||
it("emits an event when a notification is created", async () => {
|
||||
const notification = {
|
||||
to: "admin@medusa.com",
|
||||
template: "some-template",
|
||||
channel: "email",
|
||||
data: {},
|
||||
}
|
||||
|
||||
const result = await service.createNotifications(notification)
|
||||
|
||||
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(1)
|
||||
expect(eventBusEmitSpy).toHaveBeenCalledWith([
|
||||
composeMessage(NotificationEvents.NOTIFICATION_CREATED, {
|
||||
data: { id: result.id },
|
||||
object: "notification",
|
||||
source: Modules.NOTIFICATION,
|
||||
action: CommonEvents.CREATED,
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("ensures the same notification is not sent twice", async () => {
|
||||
const notification = {
|
||||
to: "admin@medusa.com",
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
NotificationTypes,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
EmitEvents,
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
@@ -17,6 +18,7 @@ import {
|
||||
} from "@medusajs/utils"
|
||||
import { Notification } from "@models"
|
||||
import NotificationProviderService from "./notification-provider"
|
||||
import { eventBuilders } from "@utils"
|
||||
|
||||
type InjectedDependencies = {
|
||||
baseRepository: DAL.RepositoryService
|
||||
@@ -64,6 +66,7 @@ export default class NotificationModuleService
|
||||
): Promise<NotificationTypes.NotificationDTO>
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
@EmitEvents()
|
||||
async createNotifications(
|
||||
data:
|
||||
| NotificationTypes.CreateNotificationDTO
|
||||
@@ -83,6 +86,11 @@ export default class NotificationModuleService
|
||||
NotificationTypes.NotificationDTO[]
|
||||
>(createdNotifications)
|
||||
|
||||
eventBuilders.createdNotification({
|
||||
data: serialized,
|
||||
sharedContext,
|
||||
})
|
||||
|
||||
return Array.isArray(data) ? serialized : serialized[0]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import {
|
||||
CommonEvents,
|
||||
eventBuilderFactory,
|
||||
Modules,
|
||||
NotificationEvents,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
export const eventBuilders = {
|
||||
createdNotification: eventBuilderFactory({
|
||||
source: Modules.NOTIFICATION,
|
||||
action: CommonEvents.CREATED,
|
||||
object: "notification",
|
||||
eventsEnum: NotificationEvents,
|
||||
}),
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./events"
|
||||
@@ -38,9 +38,9 @@ export class LocalFileService extends AbstractFileProviderService {
|
||||
|
||||
const fileKey = path.join(
|
||||
parsedFilename.dir,
|
||||
// We append "private" to the file key so deletions and presigned URLs can know which folder to look into
|
||||
`${Date.now()}-${parsedFilename.base}${
|
||||
file.access === "public" ? "" : "-private"
|
||||
// We prepend "private" to the file key so deletions and presigned URLs can know which folder to look into
|
||||
`${file.access === "public" ? "" : "private-"}${Date.now()}-${
|
||||
parsedFilename.base
|
||||
}`
|
||||
)
|
||||
|
||||
@@ -57,7 +57,7 @@ export class LocalFileService extends AbstractFileProviderService {
|
||||
}
|
||||
|
||||
async delete(file: FileTypes.ProviderDeleteFileDTO): Promise<void> {
|
||||
const baseDir = file.fileKey.endsWith("-private")
|
||||
const baseDir = file.fileKey.startsWith("private-")
|
||||
? this.privateUploadDir_
|
||||
: this.uploadDir_
|
||||
|
||||
@@ -77,7 +77,7 @@ export class LocalFileService extends AbstractFileProviderService {
|
||||
async getPresignedDownloadUrl(
|
||||
file: FileTypes.ProviderGetFileDTO
|
||||
): Promise<string> {
|
||||
const isPrivate = file.fileKey.endsWith("-private")
|
||||
const isPrivate = file.fileKey.startsWith("private-")
|
||||
const baseDir = isPrivate ? this.privateUploadDir_ : this.uploadDir_
|
||||
|
||||
const filePath = this.getUploadFilePath(baseDir, file.fileKey)
|
||||
|
||||
Reference in New Issue
Block a user