Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix new Sitemap #2262

Merged
merged 3 commits into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions package/src/node_tree.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import Sortable from "sortablejs"
import ajax from "./utils/ajax"
import { patch } from "./utils/ajax"
import { on } from "./utils/events"

function displayNodeFolders() {
document.querySelectorAll("li.menu-item").forEach((el) => {
const leftIconArea = el.querySelector(".nodes_tree-left_images")
const list = el.querySelector(".children")
const node = { folded: el.dataset.folded === "true", id: el.dataset.id, type: el.dataset.type }
const node = {
folded: el.dataset.folded === "true",
id: el.dataset.id,
type: el.dataset.type
}

if (list.children.length > 0 || node.folded) {
leftIconArea.innerHTML = HandlebarsTemplates.node_folder({ node: node })
Expand All @@ -17,13 +21,15 @@ function displayNodeFolders() {
}

function onFinishDragging(evt) {
const url = Alchemy.routes[evt.item.dataset.type].move_api_path(evt.item.dataset.id)
const url = Alchemy.routes[evt.item.dataset.type].move_api_path(
evt.item.dataset.id
)
const data = {
target_parent_id: evt.to.dataset.recordId,
new_position: evt.newIndex
}

ajax("PATCH", url, data)
patch(url, data)
.then(() => {
const message = Alchemy.t("Successfully moved menu item")
Alchemy.growl(message)
Expand All @@ -38,10 +44,11 @@ function handleNodeFolders() {
on("click", ".nodes_tree", ".node_folder", function () {
const nodeId = this.dataset.recordId
const menu_item = this.closest("li.menu-item")
const url = Alchemy.routes[this.dataset.recordType].toggle_folded_api_path(nodeId)
const url =
Alchemy.routes[this.dataset.recordType].toggle_folded_api_path(nodeId)
const list = menu_item.querySelector(".children")

ajax("PATCH", url)
patch(url)
.then(() => {
list.classList.toggle("folded")
menu_item.dataset.folded =
Expand Down
10 changes: 2 additions & 8 deletions package/src/page_sorter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Sortable from "sortablejs"
import { patch } from "./utils/ajax"

function onFinishDragging(evt) {
const pageId = evt.item.dataset.pageId
Expand All @@ -8,14 +9,7 @@ function onFinishDragging(evt) {
new_position: evt.newIndex
}

fetch(url, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(data)
})
patch(url, data)
.then(async (response) => {
const pageData = await response.json()
const pageEl = document.getElementById(`page_${pageId}`)
Expand Down
4 changes: 2 additions & 2 deletions package/src/picture_editors.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import debounce from "lodash/debounce"
import max from "lodash/max"
import ajax from "./utils/ajax"
import { get } from "./utils/ajax"
import ImageLoader from "./image_loader"

const UPDATE_DELAY = 125
Expand Down Expand Up @@ -62,7 +62,7 @@ class PictureEditor {
this.image.removeAttribute("alt")
this.image.removeAttribute("src")
this.imageLoader.load(true)
ajax("GET", `/admin/pictures/${this.pictureId}/url`, {
get(`/admin/pictures/${this.pictureId}/url`, {
crop: this.imageCropperEnabled,
crop_from: this.cropFrom,
crop_size: this.cropSize,
Expand Down
8 changes: 2 additions & 6 deletions package/src/sitemap.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// The admin sitemap Alchemy class
import PageSorter from "./page_sorter"
import { on } from "./utils/events"
import { patch } from "./utils/ajax"
import { createSortables, displayPageFolders } from "./page_sorter"

export default class Sitemap {
Expand Down Expand Up @@ -52,12 +53,7 @@ export default class Sitemap {
pageFolder.innerHTML = ""
spinner.spin(pageFolder)

fetch(Alchemy.routes.fold_admin_page_path(pageId), {
method: "PATCH",
headers: {
Accept: "application/json"
}
})
patch(Alchemy.routes.fold_admin_page_path(pageId))
.then(async (response) => {
this.reRender(pageId, await response.json())
spinner.stop()
Expand Down
78 changes: 62 additions & 16 deletions package/src/utils/__tests__/ajax.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import xhrMock from "xhr-mock"
import ajax from "../ajax"
import { get, patch, post } from "../ajax"

const token = "s3cr3t"

Expand All @@ -8,13 +8,13 @@ beforeEach(() => {
xhrMock.setup()
})

describe("ajax('get')", () => {
describe("get", () => {
it("sends X-CSRF-TOKEN header", async () => {
xhrMock.get("http://localhost/users", (req, res) => {
expect(req.header("X-CSRF-TOKEN")).toEqual(token)
return res.status(200).body('{"message":"Ok"}')
})
await ajax("get", "/users")
await get("/users")
})

it("sends Content-Type header", async () => {
Expand All @@ -24,22 +24,22 @@ describe("ajax('get')", () => {
)
return res.status(200).body('{"message":"Ok"}')
})
await ajax("get", "/users")
await get("/users")
})

it("sends Accept header", async () => {
xhrMock.get("http://localhost/users", (req, res) => {
expect(req.header("Accept")).toEqual("application/json")
return res.status(200).body('{"message":"Ok"}')
})
await ajax("get", "/users")
await get("/users")
})

it("returns JSON", async () => {
xhrMock.get("http://localhost/users", (_req, res) => {
return res.status(200).body('{"email":"mail@example.com"}')
})
await ajax("get", "/users").then((res) => {
await get("/users").then((res) => {
expect(res.data).toEqual({ email: "mail@example.com" })
})
})
Expand All @@ -49,7 +49,7 @@ describe("ajax('get')", () => {
return res.status(200).body('email => "mail@example.com"')
})
expect.assertions(1)
await ajax("get", "/users").catch((e) => {
await get("/users").catch((e) => {
expect(e.message).toMatch("Unexpected token")
})
})
Expand All @@ -59,7 +59,7 @@ describe("ajax('get')", () => {
return Promise.reject(new Error())
})
expect.assertions(1)
await ajax("get", "/users").catch((e) => {
await get("/users").catch((e) => {
expect(e.message).toEqual("An error occurred during the transaction")
})
})
Expand All @@ -69,7 +69,7 @@ describe("ajax('get')", () => {
return res.status(401).body('{"error":"Unauthorized"}')
})
expect.assertions(1)
await ajax("get", "/users").catch((e) => {
await get("/users").catch((e) => {
expect(e.error).toEqual("Unauthorized")
})
})
Expand All @@ -79,7 +79,7 @@ describe("ajax('get')", () => {
return res.status(401).body("Unauthorized")
})
expect.assertions(1)
await ajax("get", "/users").catch((e) => {
await get("/users").catch((e) => {
expect(e.message).toMatch("Unexpected token")
})
})
Expand All @@ -88,18 +88,18 @@ describe("ajax('get')", () => {
xhrMock.get("http://localhost/users?name=foo", (_req, res) => {
return res.status(200).body(`{"name":"foo"}`)
})
const { data } = await ajax("get", "/users", { name: "foo" })
const { data } = await get("/users", { name: "foo" })
expect(data.name).toEqual("foo")
})
})

describe("ajax('post')", () => {
describe("patch", () => {
it("sends X-CSRF-TOKEN header", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.header("X-CSRF-TOKEN")).toEqual(token)
return res.status(200).body('{"message":"Ok"}')
})
await ajax("post", "/users")
await patch("/users")
})

it("sends Content-Type header", async () => {
Expand All @@ -109,23 +109,69 @@ describe("ajax('post')", () => {
)
return res.status(200).body('{"message":"Ok"}')
})
await ajax("post", "/users")
await patch("/users")
})

it("sends Accept header", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.header("Accept")).toEqual("application/json")
return res.status(200).body('{"message":"Ok"}')
})
await ajax("post", "/users")
await patch("/users")
})

it("sends method override data", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.body()).toEqual('{"_method":"patch"}')
return res.status(200).body('{"message":"Ok"}')
})
await patch("/users")
})

it("sends JSON data", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.body()).toEqual(
'{"email":"mail@example.com","_method":"patch"}'
)
return res.status(200).body('{"message":"Ok"}')
})
await patch("/users", { email: "mail@example.com" })
})
})

describe("post", () => {
it("sends X-CSRF-TOKEN header", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.header("X-CSRF-TOKEN")).toEqual(token)
return res.status(200).body('{"message":"Ok"}')
})
await post("/users")
})

it("sends Content-Type header", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.header("Content-Type")).toEqual(
"application/json; charset=utf-8"
)
return res.status(200).body('{"message":"Ok"}')
})
await post("/users")
})

it("sends Accept header", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.header("Accept")).toEqual("application/json")
return res.status(200).body('{"message":"Ok"}')
})
await post("/users")
})

it("sends JSON data", async () => {
xhrMock.post("http://localhost/users", (req, res) => {
expect(req.body()).toEqual('{"email":"mail@example.com"}')
return res.status(200).body('{"message":"Ok"}')
})
await ajax("post", "/users", { email: "mail@example.com" })
await post("/users", { email: "mail@example.com" })
})
})

Expand Down
12 changes: 12 additions & 0 deletions package/src/utils/ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ function getToken() {
return metaTag.attributes.content.textContent
}

export function get(url, params) {
return ajax("GET", url, params)
}

export function patch(url, data = {}) {
return ajax("POST", url, { ...data, _method: "patch" })
}

export function post(url, data) {
return ajax("POST", url, data)
}

export default function ajax(method, path, data) {
const xhr = new XMLHttpRequest()
const promise = buildPromise(xhr)
Expand Down