feat: Add support for exporting products in backend (#8214)

CLOSES CC-221
CLOSES CC-223
CLOSES CC-224
This commit is contained in:
Stevche Radevski
2024-07-22 13:40:04 +00:00
committed by GitHub
parent e9f1aafbb1
commit 0d2e7befbd
29 changed files with 615 additions and 690 deletions
@@ -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)