chore: Improve perf of server tests (#5785)
This commit is contained in:
@@ -191,7 +191,13 @@ describe("#attachments.delete", () => {
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(200);
|
||||
expect(await Attachment.count()).toEqual(0);
|
||||
expect(
|
||||
await Attachment.count({
|
||||
where: {
|
||||
teamId: user.teamId,
|
||||
},
|
||||
})
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
it("should allow deleting an attachment without a document created by user", async () => {
|
||||
@@ -209,7 +215,13 @@ describe("#attachments.delete", () => {
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(200);
|
||||
expect(await Attachment.count()).toEqual(0);
|
||||
expect(
|
||||
await Attachment.count({
|
||||
where: {
|
||||
teamId: user.teamId,
|
||||
},
|
||||
})
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
it("should allow deleting an attachment without a document if admin", async () => {
|
||||
@@ -226,7 +238,13 @@ describe("#attachments.delete", () => {
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(200);
|
||||
expect(await Attachment.count()).toEqual(0);
|
||||
expect(
|
||||
await Attachment.count({
|
||||
where: {
|
||||
teamId: user.teamId,
|
||||
},
|
||||
})
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
it("should not allow deleting an attachment in another team", async () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { buildUser, buildTeam } from "@server/test/factories";
|
||||
import {
|
||||
getTestServer,
|
||||
@@ -5,7 +7,7 @@ import {
|
||||
setSelfHosted,
|
||||
} from "@server/test/support";
|
||||
|
||||
const mockTeamInSessionId = "1e023d05-951c-41c6-9012-c9fa0402e1c3";
|
||||
const mockTeamInSessionId = uuidv4();
|
||||
|
||||
jest.mock("@server/utils/authentication", () => ({
|
||||
getSessionsInCookie() {
|
||||
@@ -25,9 +27,7 @@ describe("#auth.info", () => {
|
||||
id: mockTeamInSessionId,
|
||||
});
|
||||
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
await buildUser();
|
||||
await buildUser({
|
||||
teamId: team2.id,
|
||||
@@ -53,9 +53,7 @@ describe("#auth.info", () => {
|
||||
|
||||
it("should require the team to not be deleted", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
await team.destroy();
|
||||
const res = await server.post("/api/auth.info", {
|
||||
body: {
|
||||
@@ -107,19 +105,20 @@ describe("#auth.config", () => {
|
||||
});
|
||||
|
||||
it("should return available providers for team subdomain", async () => {
|
||||
const subdomain = faker.internet.domainWord();
|
||||
await buildTeam({
|
||||
guestSignin: false,
|
||||
subdomain: "example",
|
||||
subdomain,
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: "123",
|
||||
providerId: uuidv4(),
|
||||
},
|
||||
],
|
||||
});
|
||||
const res = await server.post("/api/auth.config", {
|
||||
headers: {
|
||||
host: `example.outline.dev`,
|
||||
host: `${subdomain}.outline.dev`,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
@@ -129,19 +128,20 @@ describe("#auth.config", () => {
|
||||
});
|
||||
|
||||
it("should return available providers for team custom domain", async () => {
|
||||
const domain = faker.internet.domainName();
|
||||
await buildTeam({
|
||||
guestSignin: false,
|
||||
domain: "docs.mycompany.com",
|
||||
domain,
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: "123",
|
||||
providerId: uuidv4(),
|
||||
},
|
||||
],
|
||||
});
|
||||
const res = await server.post("/api/auth.config", {
|
||||
headers: {
|
||||
host: "docs.mycompany.com",
|
||||
host: domain,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
@@ -151,19 +151,20 @@ describe("#auth.config", () => {
|
||||
});
|
||||
|
||||
it("should return email provider for team when guest signin enabled", async () => {
|
||||
const subdomain = faker.internet.domainWord();
|
||||
await buildTeam({
|
||||
guestSignin: true,
|
||||
subdomain: "example",
|
||||
subdomain,
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: "123",
|
||||
providerId: uuidv4(),
|
||||
},
|
||||
],
|
||||
});
|
||||
const res = await server.post("/api/auth.config", {
|
||||
headers: {
|
||||
host: "example.outline.dev",
|
||||
host: `${subdomain}.outline.dev`,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
@@ -174,20 +175,21 @@ describe("#auth.config", () => {
|
||||
});
|
||||
|
||||
it("should not return provider when disabled", async () => {
|
||||
const subdomain = faker.internet.domainWord();
|
||||
await buildTeam({
|
||||
guestSignin: false,
|
||||
subdomain: "example",
|
||||
subdomain,
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: "123",
|
||||
providerId: uuidv4(),
|
||||
enabled: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
const res = await server.post("/api/auth.config", {
|
||||
headers: {
|
||||
host: "example.outline.dev",
|
||||
host: `${subdomain}.outline.dev`,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
@@ -204,7 +206,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: "123",
|
||||
providerId: uuidv4(),
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -223,7 +225,7 @@ describe("#auth.config", () => {
|
||||
authenticationProviders: [
|
||||
{
|
||||
name: "slack",
|
||||
providerId: "123",
|
||||
providerId: uuidv4(),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -93,9 +93,7 @@ describe("#authenticationProviders.update", () => {
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const authenticationProviders = await team.$get("authenticationProviders");
|
||||
const res = await server.post("/api/authenticationProviders.update", {
|
||||
body: {
|
||||
|
||||
@@ -7,8 +7,9 @@ import {
|
||||
buildGroup,
|
||||
buildCollection,
|
||||
buildDocument,
|
||||
buildTeam,
|
||||
} from "@server/test/factories";
|
||||
import { seed, getTestServer } from "@server/test/support";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
|
||||
const server = getTestServer();
|
||||
|
||||
@@ -21,7 +22,12 @@ describe("#collections.list", () => {
|
||||
});
|
||||
|
||||
it("should return collections", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const res = await server.post("/api/collections.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -36,7 +42,12 @@ describe("#collections.list", () => {
|
||||
});
|
||||
|
||||
it("should not return private collections actor is not a member of", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
await buildCollection({
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
@@ -143,7 +154,7 @@ describe("#collections.move", () => {
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const user = await buildUser();
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const res = await server.post("/api/collections.move", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -155,7 +166,9 @@ describe("#collections.move", () => {
|
||||
});
|
||||
|
||||
it("should return success", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const res = await server.post("/api/collections.move", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -169,7 +182,9 @@ describe("#collections.move", () => {
|
||||
});
|
||||
|
||||
it("should return error when index is not valid", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const res = await server.post("/api/collections.move", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -181,7 +196,13 @@ describe("#collections.move", () => {
|
||||
});
|
||||
|
||||
it("if index collision occurs, should updated index of other collection", async () => {
|
||||
const { user, admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const createdCollectionResponse = await server.post(
|
||||
"/api/collections.create",
|
||||
{
|
||||
@@ -209,7 +230,9 @@ describe("#collections.move", () => {
|
||||
});
|
||||
|
||||
it("if index collision with an extra collection, should updated index of other collection", async () => {
|
||||
const { user, admin } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const createdCollectionAResponse = await server.post(
|
||||
"/api/collections.create",
|
||||
{
|
||||
@@ -267,7 +290,7 @@ describe("#collections.move", () => {
|
||||
|
||||
describe("#collections.export", () => {
|
||||
it("should not allow export of private collection not a member", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
@@ -282,7 +305,9 @@ describe("#collections.export", () => {
|
||||
});
|
||||
|
||||
it("should allow export of private collection when the actor is a member", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
@@ -337,7 +362,12 @@ describe("#collections.export", () => {
|
||||
});
|
||||
|
||||
it("should return unauthorized if user is not admin", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const res = await server.post("/api/collections.export", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -384,7 +414,7 @@ describe("#collections.export_all", () => {
|
||||
});
|
||||
|
||||
it("should return success", async () => {
|
||||
const { admin } = await seed();
|
||||
const admin = await buildAdmin();
|
||||
const res = await server.post("/api/collections.export_all", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -460,7 +490,7 @@ describe("#collections.add_user", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const user = await buildUser();
|
||||
const anotherUser = await buildUser({
|
||||
teamId: user.teamId,
|
||||
@@ -623,7 +653,7 @@ describe("#collections.remove_group", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const user = await buildUser();
|
||||
const group = await buildGroup({
|
||||
teamId: user.teamId,
|
||||
@@ -694,7 +724,7 @@ describe("#collections.remove_user", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const user = await buildUser();
|
||||
const anotherUser = await buildUser({
|
||||
teamId: user.teamId,
|
||||
@@ -861,7 +891,12 @@ describe("#collections.group_memberships", () => {
|
||||
|
||||
describe("#collections.memberships", () => {
|
||||
it("should return members in private collection", async () => {
|
||||
const { collection, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
@@ -882,7 +917,12 @@ describe("#collections.memberships", () => {
|
||||
});
|
||||
|
||||
it("should allow filtering members in collection by name", async () => {
|
||||
const { collection, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const user2 = await buildUser({
|
||||
name: "Won't find",
|
||||
});
|
||||
@@ -906,7 +946,12 @@ describe("#collections.memberships", () => {
|
||||
});
|
||||
|
||||
it("should allow filtering members in collection by permission", async () => {
|
||||
const { collection, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const user2 = await buildUser();
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
@@ -941,7 +986,7 @@ describe("#collections.memberships", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/collections.memberships", {
|
||||
body: {
|
||||
@@ -955,7 +1000,12 @@ describe("#collections.memberships", () => {
|
||||
|
||||
describe("#collections.info", () => {
|
||||
it("should return collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const res = await server.post("/api/collections.info", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -968,7 +1018,12 @@ describe("#collections.info", () => {
|
||||
});
|
||||
|
||||
it("should require user member of collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.destroy({
|
||||
@@ -987,7 +1042,12 @@ describe("#collections.info", () => {
|
||||
});
|
||||
|
||||
it("should allow user member of collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
@@ -1015,7 +1075,7 @@ describe("#collections.info", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/collections.info", {
|
||||
body: {
|
||||
@@ -1067,7 +1127,7 @@ describe("#collections.create", () => {
|
||||
});
|
||||
|
||||
it("should allow setting sharing to false", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/collections.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -1082,7 +1142,7 @@ describe("#collections.create", () => {
|
||||
});
|
||||
|
||||
it("should return correct policies with private collection", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/collections.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -1098,7 +1158,7 @@ describe("#collections.create", () => {
|
||||
});
|
||||
|
||||
it("if index collision, should updated index of other collection", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const createdCollectionAResponse = await server.post(
|
||||
"/api/collections.create",
|
||||
{
|
||||
@@ -1129,7 +1189,7 @@ describe("#collections.create", () => {
|
||||
});
|
||||
|
||||
it("if index collision with an extra collection, should updated index of other collection", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const createdCollectionAResponse = await server.post(
|
||||
"/api/collections.create",
|
||||
{
|
||||
@@ -1188,7 +1248,7 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
@@ -1201,7 +1261,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing non-private collection", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -1216,7 +1278,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing sort", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const sort = {
|
||||
field: "index",
|
||||
direction: "desc",
|
||||
@@ -1235,7 +1299,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing individual fields", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -1250,7 +1316,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing from non-private to private collection, and trims whitespace", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -1269,7 +1337,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing from private to non-private collection", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
@@ -1296,7 +1366,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing by read-write collection user", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
@@ -1352,7 +1424,12 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("does not allow editing by read-only collection user", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.update(
|
||||
@@ -1378,7 +1455,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("does not allow setting unknown sort fields", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const sort = {
|
||||
field: "blah",
|
||||
direction: "desc",
|
||||
@@ -1394,7 +1473,9 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("does not allow setting unknown sort directions", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const sort = {
|
||||
field: "title",
|
||||
direction: "blah",
|
||||
@@ -1419,7 +1500,7 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const collection = await buildCollection();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/collections.delete", {
|
||||
body: {
|
||||
@@ -1431,7 +1512,9 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
|
||||
it("should not allow deleting last collection", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
const res = await server.post("/api/collections.delete", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -1442,12 +1525,11 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
|
||||
it("should delete collection", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
// to ensure it isn't the last collection
|
||||
await buildCollection({
|
||||
teamId: admin.teamId,
|
||||
createdById: admin.id,
|
||||
});
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
await buildCollection({ teamId: team.id });
|
||||
|
||||
const res = await server.post("/api/collections.delete", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -1460,7 +1542,9 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
|
||||
it("should delete published documents", async () => {
|
||||
const { admin, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
// to ensure it isn't the last collection
|
||||
await buildCollection({
|
||||
teamId: admin.teamId,
|
||||
|
||||
@@ -807,7 +807,11 @@ router.post(
|
||||
|
||||
authorize(user, "delete", collection);
|
||||
|
||||
const total = await Collection.count();
|
||||
const total = await Collection.count({
|
||||
where: {
|
||||
teamId: user.teamId,
|
||||
},
|
||||
});
|
||||
if (total === 1) {
|
||||
throw ValidationError("Cannot delete last collection");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,11 @@
|
||||
import { buildEvent, buildUser } from "@server/test/factories";
|
||||
import { seed, getTestServer, setCloudHosted } from "@server/test/support";
|
||||
import {
|
||||
buildAdmin,
|
||||
buildCollection,
|
||||
buildDocument,
|
||||
buildEvent,
|
||||
buildUser,
|
||||
} from "@server/test/factories";
|
||||
import { getTestServer, setCloudHosted } from "@server/test/support";
|
||||
|
||||
const server = getTestServer();
|
||||
|
||||
@@ -7,7 +13,17 @@ describe("#events.list", () => {
|
||||
beforeEach(setCloudHosted);
|
||||
|
||||
it("should only return activity events", async () => {
|
||||
const { user, admin, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
// audit event
|
||||
await buildEvent({
|
||||
name: "users.promote",
|
||||
@@ -35,7 +51,17 @@ describe("#events.list", () => {
|
||||
});
|
||||
|
||||
it("should return audit events", async () => {
|
||||
const { user, admin, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
// audit event
|
||||
const auditEvent = await buildEvent({
|
||||
name: "users.promote",
|
||||
@@ -65,7 +91,17 @@ describe("#events.list", () => {
|
||||
});
|
||||
|
||||
it("should allow filtering by actorId", async () => {
|
||||
const { user, admin, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
// audit event
|
||||
const auditEvent = await buildEvent({
|
||||
name: "users.promote",
|
||||
@@ -95,7 +131,17 @@ describe("#events.list", () => {
|
||||
});
|
||||
|
||||
it("should allow filtering by documentId", async () => {
|
||||
const { user, admin, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const event = await buildEvent({
|
||||
name: "documents.publish",
|
||||
collectionId: collection.id,
|
||||
@@ -116,7 +162,16 @@ describe("#events.list", () => {
|
||||
});
|
||||
|
||||
it("should not return events for documentId without authorization", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const actor = await buildUser();
|
||||
await buildEvent({
|
||||
name: "documents.publish",
|
||||
@@ -137,7 +192,17 @@ describe("#events.list", () => {
|
||||
});
|
||||
|
||||
it("should allow filtering by event name", async () => {
|
||||
const { user, admin, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
// audit event
|
||||
await buildEvent({
|
||||
name: "users.promote",
|
||||
@@ -166,7 +231,17 @@ describe("#events.list", () => {
|
||||
});
|
||||
|
||||
it("should return events with deleted actors", async () => {
|
||||
const { user, admin, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
// event viewable in activity stream
|
||||
const event = await buildEvent({
|
||||
name: "documents.publish",
|
||||
@@ -188,7 +263,7 @@ describe("#events.list", () => {
|
||||
});
|
||||
|
||||
it("should require authorization for audit events", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/events.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
|
||||
@@ -42,9 +42,7 @@ describe("#fileOperations.info", () => {
|
||||
const admin = await buildAdmin({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const exportData = await buildFileOperation({
|
||||
type: FileOperationType.Export,
|
||||
teamId: team.id,
|
||||
@@ -244,9 +242,7 @@ describe("#fileOperations.redirect", () => {
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const admin = await buildAdmin();
|
||||
const exportData = await buildFileOperation({
|
||||
state: FileOperationState.Complete,
|
||||
@@ -283,15 +279,25 @@ describe("#fileOperations.delete", () => {
|
||||
},
|
||||
});
|
||||
expect(deleteResponse.status).toBe(200);
|
||||
expect(await Event.count()).toBe(1);
|
||||
expect(await FileOperation.count()).toBe(0);
|
||||
expect(
|
||||
await Event.count({
|
||||
where: {
|
||||
teamId: team.id,
|
||||
},
|
||||
})
|
||||
).toBe(1);
|
||||
expect(
|
||||
await FileOperation.count({
|
||||
where: {
|
||||
teamId: team.id,
|
||||
},
|
||||
})
|
||||
).toBe(0);
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const admin = await buildAdmin();
|
||||
const exportData = await buildFileOperation({
|
||||
type: FileOperationType.Export,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Event } from "@server/models";
|
||||
import { Event, Group, User } from "@server/models";
|
||||
import { buildUser, buildAdmin, buildGroup } from "@server/test/factories";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
|
||||
@@ -60,8 +60,7 @@ describe("#groups.update", () => {
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
describe("when user is admin", () => {
|
||||
// @ts-expect-error ts-migrate(7034) FIXME: Variable 'user' implicitly has type 'any' in some ... Remove this comment to see the full error message
|
||||
let user, group;
|
||||
let user: User, group: Group;
|
||||
beforeEach(async () => {
|
||||
user = await buildAdmin();
|
||||
group = await buildGroup({
|
||||
@@ -71,14 +70,16 @@ describe("#groups.update", () => {
|
||||
it("allows admin to edit a group", async () => {
|
||||
const res = await server.post("/api/groups.update", {
|
||||
body: {
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'user' implicitly has an 'any' type.
|
||||
token: user.getJwtToken(),
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'group' implicitly has an 'any' type.
|
||||
id: group.id,
|
||||
name: "Test",
|
||||
},
|
||||
});
|
||||
const events = await Event.findAll();
|
||||
const events = await Event.findAll({
|
||||
where: {
|
||||
teamId: user.teamId,
|
||||
},
|
||||
});
|
||||
expect(events.length).toEqual(1);
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
@@ -87,32 +88,29 @@ describe("#groups.update", () => {
|
||||
it("does not create an event if the update is a noop", async () => {
|
||||
const res = await server.post("/api/groups.update", {
|
||||
body: {
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'user' implicitly has an 'any' type.
|
||||
token: user.getJwtToken(),
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'group' implicitly has an 'any' type.
|
||||
id: group.id,
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'group' implicitly has an 'any' type.
|
||||
name: group.name,
|
||||
},
|
||||
});
|
||||
const events = await Event.findAll();
|
||||
const events = await Event.findAll({
|
||||
where: {
|
||||
teamId: user.teamId,
|
||||
},
|
||||
});
|
||||
expect(events.length).toEqual(0);
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'group' implicitly has an 'any' type.
|
||||
expect(body.data.name).toBe(group.name);
|
||||
});
|
||||
it("fails with validation error when name already taken", async () => {
|
||||
await buildGroup({
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'user' implicitly has an 'any' type.
|
||||
teamId: user.teamId,
|
||||
name: "test",
|
||||
});
|
||||
const res = await server.post("/api/groups.update", {
|
||||
body: {
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'user' implicitly has an 'any' type.
|
||||
token: user.getJwtToken(),
|
||||
// @ts-expect-error ts-migrate(7005) FIXME: Variable 'group' implicitly has an 'any' type.
|
||||
id: group.id,
|
||||
name: "TEST",
|
||||
},
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { seed, getTestServer } from "@server/test/support";
|
||||
import { buildUser } from "@server/test/factories";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
|
||||
const server = getTestServer();
|
||||
|
||||
describe("#pagination", () => {
|
||||
it("should allow offset and limit", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -16,7 +17,7 @@ describe("#pagination", () => {
|
||||
});
|
||||
|
||||
it("should not allow negative limit", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -27,7 +28,7 @@ describe("#pagination", () => {
|
||||
});
|
||||
|
||||
it("should not allow non-integer limit", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -38,7 +39,7 @@ describe("#pagination", () => {
|
||||
});
|
||||
|
||||
it("should not allow negative offset", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -49,7 +50,7 @@ describe("#pagination", () => {
|
||||
});
|
||||
|
||||
it("should not allow non-integer offset", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
|
||||
@@ -201,9 +201,7 @@ describe("#notifications.list", () => {
|
||||
describe("#notifications.update", () => {
|
||||
it("should mark notification as viewed", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const actor = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
@@ -243,9 +241,7 @@ describe("#notifications.update", () => {
|
||||
|
||||
it("should archive the notification", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const actor = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import { CollectionUser, Revision } from "@server/models";
|
||||
import { buildDocument, buildUser } from "@server/test/factories";
|
||||
import { seed, getTestServer } from "@server/test/support";
|
||||
import {
|
||||
buildCollection,
|
||||
buildDocument,
|
||||
buildUser,
|
||||
} from "@server/test/factories";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
|
||||
const server = getTestServer();
|
||||
|
||||
describe("#revisions.info", () => {
|
||||
it("should return a document revision", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const revision = await Revision.createFromDocument(document);
|
||||
const res = await server.post("/api/revisions.info", {
|
||||
body: {
|
||||
@@ -36,7 +44,11 @@ describe("#revisions.info", () => {
|
||||
|
||||
describe("#revisions.diff", () => {
|
||||
it("should return the document HTML if no previous revision", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const revision = await Revision.createFromDocument(document);
|
||||
const res = await server.post("/api/revisions.diff", {
|
||||
body: {
|
||||
@@ -57,8 +69,13 @@ describe("#revisions.diff", () => {
|
||||
});
|
||||
|
||||
it("should allow returning HTML directly with accept header", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const revision = await Revision.createFromDocument(document);
|
||||
|
||||
const res = await server.post("/api/revisions.diff", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -81,7 +98,11 @@ describe("#revisions.diff", () => {
|
||||
});
|
||||
|
||||
it("should compare to previous revision by default", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await Revision.createFromDocument(document);
|
||||
|
||||
await document.update({ text: "New text" });
|
||||
@@ -121,7 +142,11 @@ describe("#revisions.diff", () => {
|
||||
|
||||
describe("#revisions.list", () => {
|
||||
it("should return a document's revisions", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await Revision.createFromDocument(document);
|
||||
const res = await server.post("/api/revisions.list", {
|
||||
body: {
|
||||
@@ -137,7 +162,16 @@ describe("#revisions.list", () => {
|
||||
});
|
||||
|
||||
it("should not return revisions for document in collection not a member of", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await Revision.createFromDocument(document);
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
@@ -6,9 +6,10 @@ import {
|
||||
buildShare,
|
||||
buildAdmin,
|
||||
buildCollection,
|
||||
buildTeam,
|
||||
} from "@server/test/factories";
|
||||
|
||||
import { seed, getTestServer } from "@server/test/support";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
|
||||
const server = getTestServer();
|
||||
|
||||
@@ -29,7 +30,10 @@ describe("#shares.list", () => {
|
||||
});
|
||||
|
||||
it("should only return shares created by user", async () => {
|
||||
const { user, admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const document = await buildDocument({ userId: user.id, teamId: team.id });
|
||||
await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -53,7 +57,11 @@ describe("#shares.list", () => {
|
||||
});
|
||||
|
||||
it("should not return revoked shares", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -71,7 +79,11 @@ describe("#shares.list", () => {
|
||||
});
|
||||
|
||||
it("should not return unpublished shares", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await buildShare({
|
||||
published: false,
|
||||
documentId: document.id,
|
||||
@@ -89,7 +101,11 @@ describe("#shares.list", () => {
|
||||
});
|
||||
|
||||
it("should not return shares to deleted documents", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -107,7 +123,10 @@ describe("#shares.list", () => {
|
||||
});
|
||||
|
||||
it("admins should return shares created by all users", async () => {
|
||||
const { user, admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const document = await buildDocument({ userId: user.id, teamId: team.id });
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: admin.teamId,
|
||||
@@ -126,7 +145,18 @@ describe("#shares.list", () => {
|
||||
});
|
||||
|
||||
it("admins should not return shares in collection not a member of", async () => {
|
||||
const { admin, document, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: admin.teamId,
|
||||
@@ -179,7 +209,11 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should allow creating a share record for document", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -193,7 +227,17 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should allow creating a share record with read-only permissions but no publishing", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.update(
|
||||
@@ -227,7 +271,11 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should allow creating a share record if link previously revoked", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -247,7 +295,11 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should return existing share link for document and user", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -265,9 +317,11 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should allow creating a share record if team sharing disabled but not publishing", async () => {
|
||||
const { user, document, team } = await seed();
|
||||
await team.update({
|
||||
sharing: false,
|
||||
const team = await buildTeam({ sharing: false });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const document = await buildDocument({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
});
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
@@ -288,10 +342,17 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should allow creating a share record if collection sharing disabled but not publishing", async () => {
|
||||
const { user, collection, document } = await seed();
|
||||
await collection.update({
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
sharing: false,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -311,7 +372,7 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const { document } = await seed();
|
||||
const document = await buildDocument();
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
documentId: document.id,
|
||||
@@ -323,7 +384,7 @@ describe("#shares.create", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { document } = await seed();
|
||||
const document = await buildDocument();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
@@ -390,7 +451,11 @@ describe("#shares.info", () => {
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -407,7 +472,9 @@ describe("#shares.info", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const document = await buildDocument({ teamId: team.id });
|
||||
const user = await buildUser();
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
@@ -449,7 +516,11 @@ describe("#shares.info", () => {
|
||||
});
|
||||
|
||||
it("should allow reading share by documentId", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -468,7 +539,16 @@ describe("#shares.info", () => {
|
||||
expect(body.data.shares[0].published).toBe(true);
|
||||
});
|
||||
it("should return share for parent document with includeChildDocuments=true", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const childDocument = await buildDocument({
|
||||
teamId: document.teamId,
|
||||
parentDocumentId: document.id,
|
||||
@@ -480,6 +560,7 @@ describe("#shares.info", () => {
|
||||
userId: user.id,
|
||||
includeChildDocuments: true,
|
||||
});
|
||||
await collection.reload();
|
||||
await collection.addDocumentToStructure(childDocument, 0);
|
||||
const res = await server.post("/api/shares.info", {
|
||||
body: {
|
||||
@@ -498,7 +579,17 @@ describe("#shares.info", () => {
|
||||
expect(body.policies[0].abilities.update).toBe(true);
|
||||
});
|
||||
it("should not return share for parent document with includeChildDocuments=false", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const childDocument = await buildDocument({
|
||||
teamId: document.teamId,
|
||||
parentDocumentId: document.id,
|
||||
@@ -520,7 +611,16 @@ describe("#shares.info", () => {
|
||||
expect(res.status).toEqual(204);
|
||||
});
|
||||
it("should return shares for parent document and current document", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const childDocument = await buildDocument({
|
||||
teamId: document.teamId,
|
||||
parentDocumentId: document.id,
|
||||
@@ -538,6 +638,7 @@ describe("#shares.info", () => {
|
||||
userId: user.id,
|
||||
includeChildDocuments: true,
|
||||
});
|
||||
await collection.reload();
|
||||
await collection.addDocumentToStructure(childDocument, 0);
|
||||
const res = await server.post("/api/shares.info", {
|
||||
body: {
|
||||
@@ -561,7 +662,11 @@ describe("#shares.info", () => {
|
||||
|
||||
describe("#shares.update", () => {
|
||||
it("should fail for invalid urlId", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -594,7 +699,11 @@ describe("#shares.update", () => {
|
||||
});
|
||||
|
||||
it("should update urlId", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -612,7 +721,11 @@ describe("#shares.update", () => {
|
||||
});
|
||||
|
||||
it("should allow clearing urlId", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -638,7 +751,11 @@ describe("#shares.update", () => {
|
||||
});
|
||||
|
||||
it("should allow user to update a share", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -657,7 +774,11 @@ describe("#shares.update", () => {
|
||||
});
|
||||
|
||||
it("should allow author to update a share", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -677,7 +798,10 @@ describe("#shares.update", () => {
|
||||
});
|
||||
|
||||
it("should allow admin to update a share", async () => {
|
||||
const { user, admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const document = await buildDocument({ userId: user.id, teamId: team.id });
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -697,7 +821,11 @@ describe("#shares.update", () => {
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -715,7 +843,9 @@ describe("#shares.update", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const document = await buildDocument({ teamId: team.id });
|
||||
const user = await buildUser();
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
@@ -747,7 +877,11 @@ describe("#shares.revoke", () => {
|
||||
});
|
||||
|
||||
it("should allow author to revoke a share", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -763,7 +897,11 @@ describe("#shares.revoke", () => {
|
||||
});
|
||||
|
||||
it("should 404 if shares document is deleted", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -780,7 +918,10 @@ describe("#shares.revoke", () => {
|
||||
});
|
||||
|
||||
it("should allow admin to revoke a share", async () => {
|
||||
const { user, admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const document = await buildDocument({ userId: user.id, teamId: team.id });
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -796,7 +937,11 @@ describe("#shares.revoke", () => {
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
teamId: user.teamId,
|
||||
@@ -813,7 +958,9 @@ describe("#shares.revoke", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const document = await buildDocument({ teamId: team.id });
|
||||
const user = await buildUser();
|
||||
const share = await buildShare({
|
||||
documentId: document.id,
|
||||
|
||||
@@ -54,7 +54,11 @@ describe("#subscriptions.create", () => {
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.ok).toEqual(true);
|
||||
|
||||
const events = await Event.findAll();
|
||||
const events = await Event.findAll({
|
||||
where: {
|
||||
teamId: document.teamId,
|
||||
},
|
||||
});
|
||||
|
||||
expect(events.length).toEqual(1);
|
||||
expect(events[0].name).toEqual("subscriptions.create");
|
||||
@@ -625,7 +629,11 @@ describe("#subscriptions.delete", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const events = await Event.findAll();
|
||||
const events = await Event.findAll({
|
||||
where: {
|
||||
teamId: document.teamId,
|
||||
},
|
||||
});
|
||||
|
||||
expect(events.length).toEqual(1);
|
||||
expect(events[0].name).toEqual("subscriptions.delete");
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { TeamDomain } from "@server/models";
|
||||
import { buildAdmin, buildCollection, buildTeam } from "@server/test/factories";
|
||||
import {
|
||||
seed,
|
||||
buildAdmin,
|
||||
buildCollection,
|
||||
buildTeam,
|
||||
buildUser,
|
||||
} from "@server/test/factories";
|
||||
import {
|
||||
getTestServer,
|
||||
setCloudHosted,
|
||||
setSelfHosted,
|
||||
@@ -18,24 +23,24 @@ describe("teams.create", () => {
|
||||
const res = await server.post("/api/teams.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
name: "new workspace",
|
||||
name: "factory inc",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.team.name).toEqual("new workspace");
|
||||
expect(body.data.team.subdomain).toEqual("new-workspace");
|
||||
expect(body.data.team.name).toEqual("factory inc");
|
||||
expect(body.data.team.subdomain).toEqual("factory-inc");
|
||||
});
|
||||
|
||||
it("requires a cloud hosted deployment", async () => {
|
||||
setSelfHosted();
|
||||
await setSelfHosted();
|
||||
|
||||
const team = await buildTeam();
|
||||
const user = await buildAdmin({ teamId: team.id });
|
||||
const res = await server.post("/api/teams.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
name: "new workspace",
|
||||
name: faker.company.name(),
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(402);
|
||||
@@ -44,16 +49,17 @@ describe("teams.create", () => {
|
||||
|
||||
describe("#team.update", () => {
|
||||
it("should update team details", async () => {
|
||||
const { admin } = await seed();
|
||||
const admin = await buildAdmin();
|
||||
const name = faker.company.name();
|
||||
const res = await server.post("/api/team.update", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
name: "New name",
|
||||
name,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.name).toEqual("New name");
|
||||
expect(body.data.name).toEqual(name);
|
||||
});
|
||||
|
||||
it("should not invalidate request if subdomain is sent as null", async () => {
|
||||
@@ -68,7 +74,8 @@ describe("#team.update", () => {
|
||||
});
|
||||
|
||||
it("should add new allowed Domains, removing empty string values", async () => {
|
||||
const { admin, team } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const res = await server.post("/api/team.update", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -98,10 +105,11 @@ describe("#team.update", () => {
|
||||
});
|
||||
|
||||
it("should remove old allowed Domains", async () => {
|
||||
const { admin, team } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const existingTeamDomain = await TeamDomain.create({
|
||||
teamId: team.id,
|
||||
name: "example-company.com",
|
||||
name: faker.internet.domainName(),
|
||||
createdById: admin.id,
|
||||
});
|
||||
|
||||
@@ -124,10 +132,11 @@ describe("#team.update", () => {
|
||||
});
|
||||
|
||||
it("should add new allowed domains and remove old ones", async () => {
|
||||
const { admin, team } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const existingTeamDomain = await TeamDomain.create({
|
||||
teamId: team.id,
|
||||
name: "example-company.com",
|
||||
name: faker.internet.domainName(),
|
||||
createdById: admin.id,
|
||||
});
|
||||
|
||||
@@ -155,7 +164,7 @@ describe("#team.update", () => {
|
||||
});
|
||||
|
||||
it("should only allow member,viewer or admin as default role", async () => {
|
||||
const { admin } = await seed();
|
||||
const admin = await buildAdmin();
|
||||
const res = await server.post("/api/team.update", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -175,7 +184,8 @@ describe("#team.update", () => {
|
||||
});
|
||||
|
||||
it("should allow identical team details", async () => {
|
||||
const { admin, team } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const res = await server.post("/api/team.update", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -188,18 +198,17 @@ describe("#team.update", () => {
|
||||
});
|
||||
|
||||
it("should require admin", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/team.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
name: "New name",
|
||||
name: faker.company.name(),
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
await seed();
|
||||
const res = await server.post("/api/team.update");
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import env from "@server/env";
|
||||
import { User } from "@server/models";
|
||||
import { buildDocument, buildUser } from "@server/test/factories";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
@@ -134,7 +135,7 @@ describe("#urls.unfurl", () => {
|
||||
const res = await server.post("/api/urls.unfurl", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
url: `http://localhost:3000/${document.url}`,
|
||||
url: `${env.URL}/${document.url}`,
|
||||
documentId: document.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,44 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`#users.activate should activate a suspended user 1`] = `
|
||||
{
|
||||
"data": {
|
||||
"avatarUrl": null,
|
||||
"color": "#e600e0",
|
||||
"createdAt": "2018-01-02T00:00:00.000Z",
|
||||
"email": "user1@example.com",
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
"isAdmin": false,
|
||||
"isSuspended": false,
|
||||
"isViewer": false,
|
||||
"language": "en_US",
|
||||
"lastActiveAt": null,
|
||||
"name": "User 1",
|
||||
"notificationSettings": {},
|
||||
"preferences": null,
|
||||
"updatedAt": "2018-01-02T00:00:00.000Z",
|
||||
},
|
||||
"ok": true,
|
||||
"policies": [
|
||||
{
|
||||
"abilities": {
|
||||
"activate": true,
|
||||
"delete": true,
|
||||
"demote": true,
|
||||
"promote": true,
|
||||
"read": true,
|
||||
"readDetails": true,
|
||||
"resendInvite": true,
|
||||
"suspend": true,
|
||||
"update": true,
|
||||
},
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
},
|
||||
],
|
||||
"status": 200,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.activate should require admin 1`] = `
|
||||
{
|
||||
"error": "admin_required",
|
||||
@@ -57,123 +18,6 @@ exports[`#users.delete should require authentication 1`] = `
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.demote should demote an admin 1`] = `
|
||||
{
|
||||
"data": {
|
||||
"avatarUrl": null,
|
||||
"color": "#e600e0",
|
||||
"createdAt": "2018-01-02T00:00:00.000Z",
|
||||
"email": "user1@example.com",
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
"isAdmin": false,
|
||||
"isSuspended": false,
|
||||
"isViewer": false,
|
||||
"language": "en_US",
|
||||
"lastActiveAt": null,
|
||||
"name": "User 1",
|
||||
"notificationSettings": {},
|
||||
"preferences": null,
|
||||
"updatedAt": "2018-01-02T00:00:00.000Z",
|
||||
},
|
||||
"ok": true,
|
||||
"policies": [
|
||||
{
|
||||
"abilities": {
|
||||
"activate": true,
|
||||
"delete": true,
|
||||
"demote": true,
|
||||
"promote": true,
|
||||
"read": true,
|
||||
"readDetails": true,
|
||||
"resendInvite": true,
|
||||
"suspend": true,
|
||||
"update": true,
|
||||
},
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
},
|
||||
],
|
||||
"status": 200,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.demote should demote an admin to member 1`] = `
|
||||
{
|
||||
"data": {
|
||||
"avatarUrl": null,
|
||||
"color": "#e600e0",
|
||||
"createdAt": "2018-01-02T00:00:00.000Z",
|
||||
"email": "user1@example.com",
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
"isAdmin": false,
|
||||
"isSuspended": false,
|
||||
"isViewer": false,
|
||||
"language": "en_US",
|
||||
"lastActiveAt": null,
|
||||
"name": "User 1",
|
||||
"notificationSettings": {},
|
||||
"preferences": null,
|
||||
"updatedAt": "2018-01-02T00:00:00.000Z",
|
||||
},
|
||||
"ok": true,
|
||||
"policies": [
|
||||
{
|
||||
"abilities": {
|
||||
"activate": true,
|
||||
"delete": true,
|
||||
"demote": true,
|
||||
"promote": true,
|
||||
"read": true,
|
||||
"readDetails": true,
|
||||
"resendInvite": true,
|
||||
"suspend": true,
|
||||
"update": true,
|
||||
},
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
},
|
||||
],
|
||||
"status": 200,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.demote should demote an admin to viewer 1`] = `
|
||||
{
|
||||
"data": {
|
||||
"avatarUrl": null,
|
||||
"color": "#e600e0",
|
||||
"createdAt": "2018-01-02T00:00:00.000Z",
|
||||
"email": "user1@example.com",
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
"isAdmin": false,
|
||||
"isSuspended": false,
|
||||
"isViewer": true,
|
||||
"language": "en_US",
|
||||
"lastActiveAt": null,
|
||||
"name": "User 1",
|
||||
"notificationSettings": {},
|
||||
"preferences": null,
|
||||
"updatedAt": "2018-01-02T00:00:00.000Z",
|
||||
},
|
||||
"ok": true,
|
||||
"policies": [
|
||||
{
|
||||
"abilities": {
|
||||
"activate": true,
|
||||
"delete": true,
|
||||
"demote": true,
|
||||
"promote": true,
|
||||
"read": true,
|
||||
"readDetails": true,
|
||||
"resendInvite": true,
|
||||
"suspend": true,
|
||||
"update": true,
|
||||
},
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
},
|
||||
],
|
||||
"status": 200,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.demote should not allow demoting self 1`] = `
|
||||
{
|
||||
"error": "validation_error",
|
||||
@@ -192,45 +36,6 @@ exports[`#users.demote should require admin 1`] = `
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.promote should promote a new admin 1`] = `
|
||||
{
|
||||
"data": {
|
||||
"avatarUrl": null,
|
||||
"color": "#e600e0",
|
||||
"createdAt": "2018-01-02T00:00:00.000Z",
|
||||
"email": "user1@example.com",
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
"isAdmin": true,
|
||||
"isSuspended": false,
|
||||
"isViewer": false,
|
||||
"language": "en_US",
|
||||
"lastActiveAt": null,
|
||||
"name": "User 1",
|
||||
"notificationSettings": {},
|
||||
"preferences": null,
|
||||
"updatedAt": "2018-01-02T00:00:00.000Z",
|
||||
},
|
||||
"ok": true,
|
||||
"policies": [
|
||||
{
|
||||
"abilities": {
|
||||
"activate": true,
|
||||
"delete": true,
|
||||
"demote": true,
|
||||
"promote": false,
|
||||
"read": true,
|
||||
"readDetails": true,
|
||||
"resendInvite": true,
|
||||
"suspend": true,
|
||||
"update": true,
|
||||
},
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
},
|
||||
],
|
||||
"status": 200,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.promote should require admin 1`] = `
|
||||
{
|
||||
"error": "admin_required",
|
||||
@@ -258,45 +63,6 @@ exports[`#users.suspend should require admin 1`] = `
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.suspend should suspend an user 1`] = `
|
||||
{
|
||||
"data": {
|
||||
"avatarUrl": null,
|
||||
"color": "#e600e0",
|
||||
"createdAt": "2018-01-02T00:00:00.000Z",
|
||||
"email": "user1@example.com",
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
"isAdmin": false,
|
||||
"isSuspended": true,
|
||||
"isViewer": false,
|
||||
"language": "en_US",
|
||||
"lastActiveAt": null,
|
||||
"name": "User 1",
|
||||
"notificationSettings": {},
|
||||
"preferences": null,
|
||||
"updatedAt": "2018-01-02T00:00:00.000Z",
|
||||
},
|
||||
"ok": true,
|
||||
"policies": [
|
||||
{
|
||||
"abilities": {
|
||||
"activate": true,
|
||||
"delete": true,
|
||||
"demote": false,
|
||||
"promote": false,
|
||||
"read": true,
|
||||
"readDetails": true,
|
||||
"resendInvite": true,
|
||||
"suspend": true,
|
||||
"update": true,
|
||||
},
|
||||
"id": "46fde1d4-0050-428f-9f0b-0bf77f4bdf61",
|
||||
},
|
||||
],
|
||||
"status": 200,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#users.update should require authentication 1`] = `
|
||||
{
|
||||
"error": "authentication_required",
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
buildUser,
|
||||
buildInvite,
|
||||
} from "@server/test/factories";
|
||||
import { seed, getTestServer } from "@server/test/support";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
|
||||
const server = getTestServer();
|
||||
|
||||
@@ -117,21 +117,27 @@ describe("#users.list", () => {
|
||||
});
|
||||
|
||||
it("should return teams paginated user list", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
await buildUser({ teamId: team.id });
|
||||
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
sort: "createdAt",
|
||||
direction: "DESC",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.length).toEqual(2);
|
||||
expect(body.data[0].id).toEqual(user.id);
|
||||
expect(body.data[1].id).toEqual(admin.id);
|
||||
});
|
||||
|
||||
it("should allow filtering by id", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
@@ -145,7 +151,9 @@ describe("#users.list", () => {
|
||||
});
|
||||
|
||||
it("should require admin for detailed info", async () => {
|
||||
const { user, admin } = await seed();
|
||||
const team = await buildTeam();
|
||||
await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const res = await server.post("/api/users.list", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -156,8 +164,6 @@ describe("#users.list", () => {
|
||||
expect(body.data.length).toEqual(2);
|
||||
expect(body.data[0].email).toEqual(undefined);
|
||||
expect(body.data[1].email).toEqual(undefined);
|
||||
expect(body.data[0].id).toEqual(user.id);
|
||||
expect(body.data[1].id).toEqual(admin.id);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -381,7 +387,7 @@ describe("#users.delete", () => {
|
||||
|
||||
describe("#users.update", () => {
|
||||
it("should update user profile information", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -427,7 +433,7 @@ describe("#users.update", () => {
|
||||
});
|
||||
|
||||
it("should fail upon sending invalid user preference", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -439,7 +445,7 @@ describe("#users.update", () => {
|
||||
});
|
||||
|
||||
it("should fail upon sending invalid user preference value", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -451,7 +457,7 @@ describe("#users.update", () => {
|
||||
});
|
||||
|
||||
it("should update rememberLastPath user preference", async () => {
|
||||
const { user } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/users.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -476,16 +482,17 @@ describe("#users.update", () => {
|
||||
|
||||
describe("#users.promote", () => {
|
||||
it("should promote a new admin", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
|
||||
const res = await server.post("/api/users.promote", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should require admin", async () => {
|
||||
@@ -504,7 +511,10 @@ describe("#users.promote", () => {
|
||||
|
||||
describe("#users.demote", () => {
|
||||
it("should demote an admin", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
|
||||
await user.update({
|
||||
isAdmin: true,
|
||||
}); // Make another admin
|
||||
@@ -515,13 +525,14 @@ describe("#users.demote", () => {
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should demote an admin to viewer", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
|
||||
await user.update({
|
||||
isAdmin: true,
|
||||
}); // Make another admin
|
||||
@@ -533,13 +544,14 @@ describe("#users.demote", () => {
|
||||
to: "viewer",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should demote an admin to member", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
|
||||
await user.update({
|
||||
isAdmin: true,
|
||||
}); // Make another admin
|
||||
@@ -551,9 +563,7 @@ describe("#users.demote", () => {
|
||||
to: "member",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should not allow demoting self", async () => {
|
||||
@@ -585,16 +595,17 @@ describe("#users.demote", () => {
|
||||
|
||||
describe("#users.suspend", () => {
|
||||
it("should suspend an user", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
|
||||
const res = await server.post("/api/users.suspend", {
|
||||
body: {
|
||||
token: admin.getJwtToken(),
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should not allow suspending the user themselves", async () => {
|
||||
@@ -626,7 +637,10 @@ describe("#users.suspend", () => {
|
||||
|
||||
describe("#users.activate", () => {
|
||||
it("should activate a suspended user", async () => {
|
||||
const { admin, user } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
|
||||
await user.update({
|
||||
suspendedById: admin.id,
|
||||
suspendedAt: new Date(),
|
||||
@@ -638,9 +652,7 @@ describe("#users.activate", () => {
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should require admin", async () => {
|
||||
@@ -660,9 +672,7 @@ describe("#users.activate", () => {
|
||||
describe("#users.count", () => {
|
||||
it("should count active users", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const res = await server.post("/api/users.count", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -699,9 +709,7 @@ describe("#users.count", () => {
|
||||
|
||||
it("should count suspended users", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({
|
||||
teamId: team.id,
|
||||
});
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
await buildUser({
|
||||
teamId: team.id,
|
||||
suspendedAt: new Date(),
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { View, CollectionUser } from "@server/models";
|
||||
import { buildUser } from "@server/test/factories";
|
||||
import { seed, getTestServer } from "@server/test/support";
|
||||
import {
|
||||
buildAdmin,
|
||||
buildCollection,
|
||||
buildDocument,
|
||||
buildTeam,
|
||||
buildUser,
|
||||
} from "@server/test/factories";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
|
||||
const server = getTestServer();
|
||||
|
||||
describe("#views.list", () => {
|
||||
it("should return views for a document", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await View.incrementOrCreate({
|
||||
documentId: document.id,
|
||||
userId: user.id,
|
||||
@@ -25,7 +35,10 @@ describe("#views.list", () => {
|
||||
});
|
||||
|
||||
it("should not return views for suspended user by default", async () => {
|
||||
const { user, admin, document } = await seed();
|
||||
const team = await buildTeam();
|
||||
const admin = await buildAdmin({ teamId: team.id });
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const document = await buildDocument({ userId: user.id, teamId: team.id });
|
||||
await View.incrementOrCreate({
|
||||
documentId: document.id,
|
||||
userId: user.id,
|
||||
@@ -45,7 +58,17 @@ describe("#views.list", () => {
|
||||
});
|
||||
|
||||
it("should return views for a document in read-only collection", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
@@ -71,7 +94,7 @@ describe("#views.list", () => {
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const { document } = await seed();
|
||||
const document = await buildDocument();
|
||||
const res = await server.post("/api/views.list", {
|
||||
body: {
|
||||
documentId: document.id,
|
||||
@@ -83,7 +106,7 @@ describe("#views.list", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { document } = await seed();
|
||||
const document = await buildDocument();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/views.list", {
|
||||
body: {
|
||||
@@ -97,7 +120,11 @@ describe("#views.list", () => {
|
||||
|
||||
describe("#views.create", () => {
|
||||
it("should allow creating a view record for document", async () => {
|
||||
const { user, document } = await seed();
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const res = await server.post("/api/views.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -110,7 +137,17 @@ describe("#views.create", () => {
|
||||
});
|
||||
|
||||
it("should allow creating a view record for document in read-only collection", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
@@ -131,7 +168,7 @@ describe("#views.create", () => {
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const { document } = await seed();
|
||||
const document = await buildDocument();
|
||||
const res = await server.post("/api/views.create", {
|
||||
body: {
|
||||
documentId: document.id,
|
||||
@@ -143,7 +180,7 @@ describe("#views.create", () => {
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { document } = await seed();
|
||||
const document = await buildDocument();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/views.create", {
|
||||
body: {
|
||||
|
||||
Reference in New Issue
Block a user