Make Categories a predefined list
Signed-off-by: Thomas Citharel <tcit@tcit.fr> Allow null values for categories for now Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
75554cd3f5
commit
7086fe8389
|
@ -49,12 +49,6 @@ export default class App extends Vue {
|
||||||
route: "GroupList",
|
route: "GroupList",
|
||||||
role: null
|
role: null
|
||||||
},
|
},
|
||||||
{
|
|
||||||
icon: "content_copy",
|
|
||||||
text: "Categories",
|
|
||||||
route: "CategoryList",
|
|
||||||
role: "ROLE_ADMIN"
|
|
||||||
},
|
|
||||||
{ icon: "settings", text: "Settings", role: "ROLE_USER" },
|
{ icon: "settings", text: "Settings", role: "ROLE_USER" },
|
||||||
{ icon: "chat_bubble", text: "Send feedback", role: "ROLE_USER" },
|
{ icon: "chat_bubble", text: "Send feedback", role: "ROLE_USER" },
|
||||||
{ icon: "help", text: "Help", role: null },
|
{ icon: "help", text: "Help", role: null },
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import gql from 'graphql-tag';
|
|
||||||
|
|
||||||
export const FETCH_CATEGORIES = gql`
|
|
||||||
query {
|
|
||||||
categories {
|
|
||||||
id,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
picture {
|
|
||||||
url,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const CREATE_CATEGORY = gql`
|
|
||||||
mutation createCategory($title: String!, $description: String!, $picture: Upload!) {
|
|
||||||
createCategory(title: $title, description: $description, picture: $picture) {
|
|
||||||
id,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
picture {
|
|
||||||
url,
|
|
||||||
url_thumbnail
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
`;
|
|
|
@ -25,6 +25,7 @@ export const FETCH_EVENT = gql`
|
||||||
thumbnail,
|
thumbnail,
|
||||||
large_image,
|
large_image,
|
||||||
publish_at,
|
publish_at,
|
||||||
|
category,
|
||||||
# online_address,
|
# online_address,
|
||||||
# phone_address,
|
# phone_address,
|
||||||
organizerActor {
|
organizerActor {
|
||||||
|
@ -39,10 +40,7 @@ export const FETCH_EVENT = gql`
|
||||||
# },
|
# },
|
||||||
participants {
|
participants {
|
||||||
${participantQuery}
|
${participantQuery}
|
||||||
},
|
}
|
||||||
category {
|
|
||||||
title,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -75,9 +73,7 @@ export const FETCH_EVENTS = gql`
|
||||||
preferredUsername,
|
preferredUsername,
|
||||||
name,
|
name,
|
||||||
},
|
},
|
||||||
category {
|
category,
|
||||||
title,
|
|
||||||
},
|
|
||||||
participants {
|
participants {
|
||||||
${participantQuery}
|
${participantQuery}
|
||||||
}
|
}
|
||||||
|
@ -112,9 +108,9 @@ export const EDIT_EVENT = gql`
|
||||||
$title: String!,
|
$title: String!,
|
||||||
$description: String!,
|
$description: String!,
|
||||||
$organizerActorId: Int!,
|
$organizerActorId: Int!,
|
||||||
$categoryId: Int!
|
$category: String!
|
||||||
) {
|
) {
|
||||||
EditEvent(title: $title, description: $description, organizerActorId: $organizerActorId, categoryId: $categoryId) {
|
EditEvent(title: $title, description: $description, organizerActorId: $organizerActorId, category: $category) {
|
||||||
uuid
|
uuid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
import CategoryList from '@/views/Category/List.vue';
|
|
||||||
import CreateCategory from '@/views/Category/Create.vue';
|
|
||||||
|
|
||||||
export enum CategoryRouteName {
|
|
||||||
CATEGORY_LIST = 'CategoryList',
|
|
||||||
CREATE_CATEGORY = 'CreateCategory',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const categoryRoutes = [
|
|
||||||
{
|
|
||||||
path: '/category',
|
|
||||||
name: CategoryRouteName.CATEGORY_LIST,
|
|
||||||
component: CategoryList,
|
|
||||||
meta: { requiredAuth: false },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/category/create',
|
|
||||||
name: CategoryRouteName.CREATE_CATEGORY,
|
|
||||||
component: CreateCategory,
|
|
||||||
meta: { requiredAuth: true },
|
|
||||||
},
|
|
||||||
];
|
|
|
@ -5,7 +5,6 @@ import Home from '@/views/Home.vue';
|
||||||
import { UserRouteName, userRoutes } from './user';
|
import { UserRouteName, userRoutes } from './user';
|
||||||
import { EventRouteName, eventRoutes } from '@/router/event';
|
import { EventRouteName, eventRoutes } from '@/router/event';
|
||||||
import { ActorRouteName, actorRoutes } from '@/router/actor';
|
import { ActorRouteName, actorRoutes } from '@/router/actor';
|
||||||
import { CategoryRouteName, categoryRoutes } from '@/router/category';
|
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
|
@ -20,7 +19,6 @@ export const RouteName = {
|
||||||
...GlobalRouteName,
|
...GlobalRouteName,
|
||||||
...UserRouteName,
|
...UserRouteName,
|
||||||
...EventRouteName,
|
...EventRouteName,
|
||||||
...CategoryRouteName,
|
|
||||||
...ActorRouteName,
|
...ActorRouteName,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +28,6 @@ const router = new Router({
|
||||||
routes: [
|
routes: [
|
||||||
...userRoutes,
|
...userRoutes,
|
||||||
...eventRoutes,
|
...eventRoutes,
|
||||||
...categoryRoutes,
|
|
||||||
...actorRoutes,
|
...actorRoutes,
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,10 +27,12 @@ export enum ParticipantRole {
|
||||||
CREATOR = 'creator',
|
CREATOR = 'creator',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICategory {
|
export enum Category {
|
||||||
title: string;
|
BUSINESS = 'business',
|
||||||
description: string;
|
CONFERENCE = 'conference',
|
||||||
picture: string;
|
BIRTHDAY = 'birthday',
|
||||||
|
DEMONSTRATION = 'demonstration',
|
||||||
|
MEETING = 'meeting',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IParticipant {
|
export interface IParticipant {
|
||||||
|
@ -47,7 +49,7 @@ export interface IEvent {
|
||||||
|
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
category: ICategory;
|
category: Category;
|
||||||
|
|
||||||
begins_on: Date;
|
begins_on: Date;
|
||||||
ends_on: Date;
|
ends_on: Date;
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
<template>
|
|
||||||
<section>
|
|
||||||
<h1 class="title">
|
|
||||||
<translate>Create a new category</translate>
|
|
||||||
</h1>
|
|
||||||
<div class="columns">
|
|
||||||
<form class="column" @submit="submit">
|
|
||||||
<b-field :label="$gettext('Name of the category')">
|
|
||||||
<b-input aria-required="true" required v-model="category.title"/>
|
|
||||||
</b-field>
|
|
||||||
|
|
||||||
<b-field :label="$gettext('Description')">
|
|
||||||
<b-input type="textarea" v-model="category.description"/>
|
|
||||||
</b-field>
|
|
||||||
|
|
||||||
<b-field class="file">
|
|
||||||
<b-upload v-model="file" @input="onFilePicked">
|
|
||||||
<a class="button is-primary">
|
|
||||||
<b-icon icon="upload"></b-icon>
|
|
||||||
<span>
|
|
||||||
<translate>Click to upload</translate>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</b-upload>
|
|
||||||
<span class="file-name" v-if="file">{{ this.image.name }}</span>
|
|
||||||
</b-field>
|
|
||||||
|
|
||||||
<button class="button is-primary">
|
|
||||||
<translate>Create the category</translate>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { CREATE_CATEGORY } from "@/graphql/category";
|
|
||||||
import { Component, Vue } from "vue-property-decorator";
|
|
||||||
import { ICategory } from "@/types/event.model";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO : No picture is uploaded ATM
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Component
|
|
||||||
export default class CreateCategory extends Vue {
|
|
||||||
category!: ICategory;
|
|
||||||
image = {
|
|
||||||
name: ""
|
|
||||||
} as { name: string };
|
|
||||||
file: any = null;
|
|
||||||
|
|
||||||
create() {
|
|
||||||
this.$apollo
|
|
||||||
.mutate({
|
|
||||||
mutation: CREATE_CATEGORY,
|
|
||||||
variables: this.category
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
console.log(data);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO : Check if we can upload as soon as file is picked and purge files not validated
|
|
||||||
onFilePicked(e) {
|
|
||||||
if (e === undefined || e.name.lastIndexOf(".") <= 0) {
|
|
||||||
console.error("File is incorrect");
|
|
||||||
}
|
|
||||||
this.image.name = e.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,55 +0,0 @@
|
||||||
<template>
|
|
||||||
<section>
|
|
||||||
<h1 class="title">
|
|
||||||
<translate>Category List</translate>
|
|
||||||
</h1>
|
|
||||||
<b-loading :active.sync="$apollo.loading"></b-loading>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column card" v-for="category in categories" :key="category.id">
|
|
||||||
<div class="card-image">
|
|
||||||
<figure class="image is-4by3">
|
|
||||||
<img v-if="category.picture.url" :src="HTTP_ENDPOINT + category.picture.url">
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
<div class="card-content">
|
|
||||||
<h2 class="title is-4">{{ category.title }}</h2>
|
|
||||||
<p>{{ category.description }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { FETCH_CATEGORIES } from "@/graphql/category";
|
|
||||||
import { Component, Vue } from "vue-property-decorator";
|
|
||||||
|
|
||||||
// TODO : remove this hardcode
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
apollo: {
|
|
||||||
categories: {
|
|
||||||
query: FETCH_CATEGORIES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
export default class List extends Vue {
|
|
||||||
categories = [];
|
|
||||||
loading = true;
|
|
||||||
HTTP_ENDPOINT = "http://localhost:4000";
|
|
||||||
|
|
||||||
deleteCategory(categoryId) {
|
|
||||||
const router = this.$router;
|
|
||||||
// FIXME: remove eventFetch
|
|
||||||
// eventFetch(`/categories/${categoryId}`, this.$store, { method: 'DELETE' })
|
|
||||||
// .then(() => {
|
|
||||||
// this.categories = this.categories.filter(category => category.id !== categoryId);
|
|
||||||
// router.push('/category');
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import {Category} from "../../types/event.model";
|
||||||
import {EventJoinOptions} from "../../types/event.model";
|
import {EventJoinOptions} from "../../types/event.model";
|
||||||
<template>
|
<template>
|
||||||
<section>
|
<section>
|
||||||
|
@ -18,8 +19,8 @@ import {EventJoinOptions} from "../../types/event.model";
|
||||||
<option
|
<option
|
||||||
v-for="category in categories"
|
v-for="category in categories"
|
||||||
:value="category"
|
:value="category"
|
||||||
:key="category.title"
|
:key="category"
|
||||||
>{{ category.title }}</option>
|
>{{ $gettext(category) }}</option>
|
||||||
</b-select>
|
</b-select>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
|
@ -32,30 +33,24 @@ import {EventJoinOptions} from "../../types/event.model";
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// import Location from '@/components/Location';
|
// import Location from '@/components/Location';
|
||||||
import VueMarkdown from "vue-markdown";
|
import VueMarkdown from "vue-markdown";
|
||||||
import {CREATE_EVENT, EDIT_EVENT} from "@/graphql/event";
|
import {CREATE_EVENT, EDIT_EVENT} from "@/graphql/event";
|
||||||
import {FETCH_CATEGORIES} from "@/graphql/category";
|
import {Component, Prop, Vue} from "vue-property-decorator";
|
||||||
import {Component, Prop, Vue} from "vue-property-decorator";
|
import {Category, EventJoinOptions, EventStatus, EventVisibility, IEvent} from "@/types/event.model";
|
||||||
import {EventJoinOptions, EventStatus, EventVisibility, ICategory, IEvent} from "@/types/event.model";
|
import {LOGGED_PERSON} from "@/graphql/actor";
|
||||||
import {LOGGED_PERSON} from "@/graphql/actor";
|
import {IPerson} from "@/types/actor.model";
|
||||||
import {IPerson} from "@/types/actor.model";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
VueMarkdown
|
VueMarkdown
|
||||||
},
|
|
||||||
apollo: {
|
|
||||||
categories: {
|
|
||||||
query: FETCH_CATEGORIES
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export default class CreateEvent extends Vue {
|
export default class CreateEvent extends Vue {
|
||||||
@Prop({ required: false, type: String }) uuid!: string;
|
@Prop({ required: false, type: String }) uuid!: string;
|
||||||
|
|
||||||
loggedPerson!: IPerson;
|
loggedPerson!: IPerson;
|
||||||
categories: ICategory[] = [];
|
categories: string[] = Object.keys(Category);
|
||||||
event!: IEvent; // FIXME: correctly type an event
|
event!: IEvent; // FIXME: correctly type an event
|
||||||
|
|
||||||
// created() {
|
// created() {
|
||||||
|
@ -77,7 +72,7 @@ export default class CreateEvent extends Vue {
|
||||||
description: "",
|
description: "",
|
||||||
begins_on: new Date(),
|
begins_on: new Date(),
|
||||||
ends_on: new Date(),
|
ends_on: new Date(),
|
||||||
category: this.categories[0],
|
category: Category.MEETING,
|
||||||
participants: [],
|
participants: [],
|
||||||
uuid: "",
|
uuid: "",
|
||||||
url: "",
|
url: "",
|
||||||
|
@ -102,7 +97,7 @@ export default class CreateEvent extends Vue {
|
||||||
title: this.event.title,
|
title: this.event.title,
|
||||||
description: this.event.description,
|
description: this.event.description,
|
||||||
beginsOn: this.event.begins_on,
|
beginsOn: this.event.begins_on,
|
||||||
category: this.event.category.title,
|
category: this.event.category,
|
||||||
organizerActorId: this.event.organizerActor.id
|
organizerActorId: this.event.organizerActor.id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<span>{{ event.begins_on | formatDay }}</span>
|
<span>{{ event.begins_on | formatDay }}</span>
|
||||||
<span class="tag is-primary">{{ event.category.title }}</span>
|
<span class="tag is-primary">{{ event.category }}</span>
|
||||||
<h1 class="title">{{ event.title }}</h1>
|
<h1 class="title">{{ event.title }}</h1>
|
||||||
<router-link
|
<router-link
|
||||||
:to="{name: 'Profile', params: { name: event.organizerActor.preferredUsername } }"
|
:to="{name: 'Profile', params: { name: event.organizerActor.preferredUsername } }"
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
defmodule Mobilizon.Events.Category do
|
|
||||||
@moduledoc """
|
|
||||||
Represents a category for events
|
|
||||||
"""
|
|
||||||
use Ecto.Schema
|
|
||||||
import Ecto.Changeset
|
|
||||||
alias Mobilizon.Events.Category
|
|
||||||
use Arc.Ecto.Schema
|
|
||||||
|
|
||||||
schema "categories" do
|
|
||||||
field(:description, :string)
|
|
||||||
field(:picture, MobilizonWeb.Uploaders.Category.Type)
|
|
||||||
field(:title, :string, null: false)
|
|
||||||
|
|
||||||
timestamps()
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc false
|
|
||||||
def changeset(%Category{} = category, attrs) do
|
|
||||||
category
|
|
||||||
|> cast(attrs, [:title, :description])
|
|
||||||
|> cast_attachments(attrs, [:picture])
|
|
||||||
|> validate_required([:title])
|
|
||||||
|> unique_constraint(:title)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -19,13 +19,21 @@ defenum(Mobilizon.Events.EventStatusEnum, :event_status_type, [
|
||||||
:cancelled
|
:cancelled
|
||||||
])
|
])
|
||||||
|
|
||||||
|
defenum(Mobilizon.Event.EventCategoryEnum, :event_category_type, [
|
||||||
|
:business,
|
||||||
|
:conference,
|
||||||
|
:birthday,
|
||||||
|
:demonstration,
|
||||||
|
:meeting
|
||||||
|
])
|
||||||
|
|
||||||
defmodule Mobilizon.Events.Event do
|
defmodule Mobilizon.Events.Event do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Represents an event
|
Represents an event
|
||||||
"""
|
"""
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
alias Mobilizon.Events.{Event, Participant, Tag, Category, Session, Track}
|
alias Mobilizon.Events.{Event, Participant, Tag, Session, Track}
|
||||||
alias Mobilizon.Actors.Actor
|
alias Mobilizon.Actors.Actor
|
||||||
alias Mobilizon.Addresses.Address
|
alias Mobilizon.Addresses.Address
|
||||||
|
|
||||||
|
@ -45,10 +53,10 @@ defmodule Mobilizon.Events.Event do
|
||||||
field(:uuid, Ecto.UUID, default: Ecto.UUID.generate())
|
field(:uuid, Ecto.UUID, default: Ecto.UUID.generate())
|
||||||
field(:online_address, :string)
|
field(:online_address, :string)
|
||||||
field(:phone_address, :string)
|
field(:phone_address, :string)
|
||||||
|
field(:category, :string)
|
||||||
belongs_to(:organizer_actor, Actor, foreign_key: :organizer_actor_id)
|
belongs_to(:organizer_actor, Actor, foreign_key: :organizer_actor_id)
|
||||||
belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id)
|
belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id)
|
||||||
many_to_many(:tags, Tag, join_through: "events_tags")
|
many_to_many(:tags, Tag, join_through: "events_tags")
|
||||||
belongs_to(:category, Category)
|
|
||||||
many_to_many(:participants, Actor, join_through: Participant)
|
many_to_many(:participants, Actor, join_through: Participant)
|
||||||
has_many(:tracks, Track)
|
has_many(:tracks, Track)
|
||||||
has_many(:sessions, Session)
|
has_many(:sessions, Session)
|
||||||
|
@ -67,7 +75,7 @@ defmodule Mobilizon.Events.Event do
|
||||||
:begins_on,
|
:begins_on,
|
||||||
:ends_on,
|
:ends_on,
|
||||||
:organizer_actor_id,
|
:organizer_actor_id,
|
||||||
:category_id,
|
:category,
|
||||||
:status,
|
:status,
|
||||||
:visibility,
|
:visibility,
|
||||||
:thumbnail,
|
:thumbnail,
|
||||||
|
@ -83,7 +91,7 @@ defmodule Mobilizon.Events.Event do
|
||||||
:title,
|
:title,
|
||||||
:begins_on,
|
:begins_on,
|
||||||
:organizer_actor_id,
|
:organizer_actor_id,
|
||||||
:category_id,
|
:category,
|
||||||
:url,
|
:url,
|
||||||
:uuid
|
:uuid
|
||||||
])
|
])
|
||||||
|
|
|
@ -27,7 +27,6 @@ defmodule Mobilizon.Events do
|
||||||
order_by: [desc: :id],
|
order_by: [desc: :id],
|
||||||
preload: [
|
preload: [
|
||||||
:organizer_actor,
|
:organizer_actor,
|
||||||
:category,
|
|
||||||
:sessions,
|
:sessions,
|
||||||
:tracks,
|
:tracks,
|
||||||
:tags,
|
:tags,
|
||||||
|
@ -145,7 +144,6 @@ defmodule Mobilizon.Events do
|
||||||
where: e.uuid == ^uuid and e.visibility in [^:public, ^:unlisted],
|
where: e.uuid == ^uuid and e.visibility in [^:public, ^:unlisted],
|
||||||
preload: [
|
preload: [
|
||||||
:organizer_actor,
|
:organizer_actor,
|
||||||
:category,
|
|
||||||
:sessions,
|
:sessions,
|
||||||
:tracks,
|
:tracks,
|
||||||
:tags,
|
:tags,
|
||||||
|
@ -164,7 +162,6 @@ defmodule Mobilizon.Events do
|
||||||
|
|
||||||
Repo.preload(event, [
|
Repo.preload(event, [
|
||||||
:organizer_actor,
|
:organizer_actor,
|
||||||
:category,
|
|
||||||
:sessions,
|
:sessions,
|
||||||
:tracks,
|
:tracks,
|
||||||
:tags,
|
:tags,
|
||||||
|
@ -182,7 +179,6 @@ defmodule Mobilizon.Events do
|
||||||
where: e.url == ^url and e.visibility in [^:public, ^:unlisted],
|
where: e.url == ^url and e.visibility in [^:public, ^:unlisted],
|
||||||
preload: [
|
preload: [
|
||||||
:organizer_actor,
|
:organizer_actor,
|
||||||
:category,
|
|
||||||
:sessions,
|
:sessions,
|
||||||
:tracks,
|
:tracks,
|
||||||
:tags,
|
:tags,
|
||||||
|
@ -205,7 +201,6 @@ defmodule Mobilizon.Events do
|
||||||
where: e.url == ^url and e.visibility in [^:public, ^:unlisted],
|
where: e.url == ^url and e.visibility in [^:public, ^:unlisted],
|
||||||
preload: [
|
preload: [
|
||||||
:organizer_actor,
|
:organizer_actor,
|
||||||
:category,
|
|
||||||
:sessions,
|
:sessions,
|
||||||
:tracks,
|
:tracks,
|
||||||
:tags,
|
:tags,
|
||||||
|
@ -350,110 +345,6 @@ defmodule Mobilizon.Events do
|
||||||
Event.changeset(event, %{})
|
Event.changeset(event, %{})
|
||||||
end
|
end
|
||||||
|
|
||||||
alias Mobilizon.Events.Category
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Returns the list of categories.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> list_categories()
|
|
||||||
[%Category{}, ...]
|
|
||||||
|
|
||||||
"""
|
|
||||||
def list_categories(page \\ nil, limit \\ nil) do
|
|
||||||
Repo.all(
|
|
||||||
Category
|
|
||||||
|> paginate(page, limit)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Gets a single category.
|
|
||||||
|
|
||||||
Raises `Ecto.NoResultsError` if the Category does not exist.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> get_category!(123)
|
|
||||||
%Category{}
|
|
||||||
|
|
||||||
iex> get_category!(456)
|
|
||||||
** (Ecto.NoResultsError)
|
|
||||||
|
|
||||||
"""
|
|
||||||
def get_category!(id), do: Repo.get!(Category, id)
|
|
||||||
|
|
||||||
@spec get_category_by_title(String.t()) :: Category.t() | nil
|
|
||||||
def get_category_by_title(title) when is_binary(title) do
|
|
||||||
Repo.get_by(Category, title: title)
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Creates a category.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> create_category(%{field: value})
|
|
||||||
{:ok, %Category{}}
|
|
||||||
|
|
||||||
iex> create_category(%{field: bad_value})
|
|
||||||
{:error, %Ecto.Changeset{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def create_category(attrs \\ %{}) do
|
|
||||||
%Category{}
|
|
||||||
|> Category.changeset(attrs)
|
|
||||||
|> Repo.insert()
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Updates a category.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> update_category(category, %{field: new_value})
|
|
||||||
{:ok, %Category{}}
|
|
||||||
|
|
||||||
iex> update_category(category, %{field: bad_value})
|
|
||||||
{:error, %Ecto.Changeset{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def update_category(%Category{} = category, attrs) do
|
|
||||||
category
|
|
||||||
|> Category.changeset(attrs)
|
|
||||||
|> Repo.update()
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Deletes a Category.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> delete_category(category)
|
|
||||||
{:ok, %Category{}}
|
|
||||||
|
|
||||||
iex> delete_category(category)
|
|
||||||
{:error, %Ecto.Changeset{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def delete_category(%Category{} = category) do
|
|
||||||
Repo.delete(category)
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Returns an `%Ecto.Changeset{}` for tracking category changes.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> change_category(category)
|
|
||||||
%Ecto.Changeset{source: %Category{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def change_category(%Category{} = category) do
|
|
||||||
Category.changeset(category, %{})
|
|
||||||
end
|
|
||||||
|
|
||||||
alias Mobilizon.Events.Tag
|
alias Mobilizon.Events.Tag
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
defmodule MobilizonWeb.Resolvers.Category do
|
|
||||||
@moduledoc """
|
|
||||||
Handles the category-related GraphQL calls
|
|
||||||
"""
|
|
||||||
require Logger
|
|
||||||
alias Mobilizon.Actors.User
|
|
||||||
|
|
||||||
###
|
|
||||||
# TODO : Refactor this into MobilizonWeb.API.Categories when a standard AS category is defined
|
|
||||||
###
|
|
||||||
def list_categories(_parent, %{page: page, limit: limit}, _resolution) do
|
|
||||||
categories =
|
|
||||||
Mobilizon.Events.list_categories(page, limit)
|
|
||||||
|> Enum.map(fn category ->
|
|
||||||
urls = MobilizonWeb.Uploaders.Category.urls({category.picture, category})
|
|
||||||
Map.put(category, :picture, %{url: urls.original, url_thumbnail: urls.thumb})
|
|
||||||
end)
|
|
||||||
|
|
||||||
{:ok, categories}
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_category(_parent, %{title: title, picture: picture, description: description}, %{
|
|
||||||
context: %{current_user: %User{} = _user}
|
|
||||||
}) do
|
|
||||||
with {:ok, category} <-
|
|
||||||
Mobilizon.Events.create_category(%{
|
|
||||||
title: title,
|
|
||||||
description: description,
|
|
||||||
picture: picture
|
|
||||||
}),
|
|
||||||
urls <- MobilizonWeb.Uploaders.Category.urls({category.picture, category}) do
|
|
||||||
Logger.info("Created category " <> title)
|
|
||||||
{:ok, Map.put(category, :picture, %{url: urls.original, url_thumbnail: urls.thumb})}
|
|
||||||
else
|
|
||||||
{:error, %Ecto.Changeset{errors: errors} = _changeset} ->
|
|
||||||
# This is pretty ridiculous for changeset to error
|
|
||||||
errors =
|
|
||||||
Enum.into(errors, %{})
|
|
||||||
|> Enum.map(fn {key, {value, _}} -> Atom.to_string(key) <> ": " <> value end)
|
|
||||||
|
|
||||||
{:error, errors}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_category(_parent, _args, %{}) do
|
|
||||||
{:error, "You are not allowed to create a category if not connected"}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -130,7 +130,6 @@ defmodule MobilizonWeb.Schema do
|
||||||
import_fields(:group_queries)
|
import_fields(:group_queries)
|
||||||
import_fields(:event_queries)
|
import_fields(:event_queries)
|
||||||
import_fields(:participant_queries)
|
import_fields(:participant_queries)
|
||||||
import_fields(:category_queries)
|
|
||||||
import_fields(:tag_queries)
|
import_fields(:tag_queries)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -142,7 +141,6 @@ defmodule MobilizonWeb.Schema do
|
||||||
import_fields(:person_mutations)
|
import_fields(:person_mutations)
|
||||||
import_fields(:group_mutations)
|
import_fields(:group_mutations)
|
||||||
import_fields(:event_mutations)
|
import_fields(:event_mutations)
|
||||||
import_fields(:category_mutations)
|
|
||||||
import_fields(:comment_mutations)
|
import_fields(:comment_mutations)
|
||||||
import_fields(:participant_mutations)
|
import_fields(:participant_mutations)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||||
import_types(MobilizonWeb.Schema.AddressType)
|
import_types(MobilizonWeb.Schema.AddressType)
|
||||||
import_types(MobilizonWeb.Schema.Events.ParticipantType)
|
import_types(MobilizonWeb.Schema.Events.ParticipantType)
|
||||||
import_types(MobilizonWeb.Schema.Events.CategoryType)
|
|
||||||
import_types(MobilizonWeb.Schema.TagType)
|
import_types(MobilizonWeb.Schema.TagType)
|
||||||
alias MobilizonWeb.Resolvers
|
alias MobilizonWeb.Resolvers
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||||
description: "The event's tags"
|
description: "The event's tags"
|
||||||
)
|
)
|
||||||
|
|
||||||
field(:category, :category, description: "The event's category")
|
field(:category, :string, description: "The event's category")
|
||||||
|
|
||||||
field(:participants, list_of(:participant),
|
field(:participants, list_of(:participant),
|
||||||
resolve: &MobilizonWeb.Resolvers.Event.list_participants_for_event/3,
|
resolve: &MobilizonWeb.Resolvers.Event.list_participants_for_event/3,
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
defmodule MobilizonWeb.Schema.Events.CategoryType do
|
|
||||||
@moduledoc """
|
|
||||||
Schema representation for Category
|
|
||||||
"""
|
|
||||||
use Absinthe.Schema.Notation
|
|
||||||
alias MobilizonWeb.Resolvers
|
|
||||||
|
|
||||||
@desc "A category"
|
|
||||||
object :category do
|
|
||||||
field(:id, :id, description: "The category's ID")
|
|
||||||
field(:description, :string, description: "The category's description")
|
|
||||||
field(:picture, :picture, description: "The category's picture")
|
|
||||||
field(:title, :string, description: "The category's title")
|
|
||||||
end
|
|
||||||
|
|
||||||
object :category_queries do
|
|
||||||
@desc "Get the list of categories"
|
|
||||||
field :categories, non_null(list_of(:category)) do
|
|
||||||
arg(:page, :integer, default_value: 1)
|
|
||||||
arg(:limit, :integer, default_value: 10)
|
|
||||||
resolve(&Resolvers.Category.list_categories/3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
object :category_mutations do
|
|
||||||
@desc "Create a category with a title, description and picture"
|
|
||||||
field :create_category, type: :category do
|
|
||||||
arg(:title, non_null(:string))
|
|
||||||
arg(:description, non_null(:string))
|
|
||||||
arg(:picture, non_null(:upload))
|
|
||||||
resolve(&Resolvers.Category.create_category/3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -30,10 +30,9 @@ defmodule MobilizonWeb.Uploaders.Category do
|
||||||
"#{title}_#{version}"
|
"#{title}_#{version}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO : When we're sure creating a category is secured and made possible only for admins, use category name
|
|
||||||
# Override the storage directory:
|
# Override the storage directory:
|
||||||
def storage_dir(_, _) do
|
def storage_dir(_, _) do
|
||||||
"uploads/categories/"
|
"uploads/event/"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Provide a default URL if there hasn't been a file uploaded
|
# Provide a default URL if there hasn't been a file uploaded
|
|
@ -1,6 +1,5 @@
|
||||||
defmodule MobilizonWeb.ActivityPub.ObjectView do
|
defmodule MobilizonWeb.ActivityPub.ObjectView do
|
||||||
use MobilizonWeb, :view
|
use MobilizonWeb, :view
|
||||||
alias MobilizonWeb.ActivityPub.ObjectView
|
|
||||||
alias Mobilizon.Service.ActivityPub.Utils
|
alias Mobilizon.Service.ActivityPub.Utils
|
||||||
|
|
||||||
def render("event.json", %{event: event}) do
|
def render("event.json", %{event: event}) do
|
||||||
|
@ -9,7 +8,7 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
|
||||||
"actor" => event["actor"],
|
"actor" => event["actor"],
|
||||||
"id" => event["id"],
|
"id" => event["id"],
|
||||||
"name" => event["title"],
|
"name" => event["title"],
|
||||||
"category" => render_one(event["category"], ObjectView, "category.json", as: :category),
|
"category" => event["category"],
|
||||||
"content" => event["summary"],
|
"content" => event["summary"],
|
||||||
"mediaType" => "text/html"
|
"mediaType" => "text/html"
|
||||||
# "published" => Timex.format!(event.inserted_at, "{ISO:Extended}"),
|
# "published" => Timex.format!(event.inserted_at, "{ISO:Extended}"),
|
||||||
|
@ -35,15 +34,4 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
|
||||||
|
|
||||||
Map.merge(comment, Utils.make_json_ld_header())
|
Map.merge(comment, Utils.make_json_ld_header())
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("category.json", %{category: category}) when not is_nil(category) do
|
|
||||||
%{
|
|
||||||
"identifier" => category.id,
|
|
||||||
"name" => category.title
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def render("category.json", %{category: _category}) do
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias Mobilizon.Events
|
alias Mobilizon.Events
|
||||||
alias Mobilizon.Events.{Event, Category, Comment}
|
alias Mobilizon.Events.{Event, Comment}
|
||||||
alias Mobilizon.Service.ActivityPub.Transmogrifier
|
alias Mobilizon.Service.ActivityPub.Transmogrifier
|
||||||
alias Mobilizon.Service.WebFinger
|
alias Mobilizon.Service.WebFinger
|
||||||
alias Mobilizon.Activity
|
alias Mobilizon.Activity
|
||||||
|
@ -565,23 +565,8 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||||
# TODO : Use MobilizonWeb.API instead
|
# TODO : Use MobilizonWeb.API instead
|
||||||
# TODO : refactor me and move me somewhere else!
|
# TODO : refactor me and move me somewhere else!
|
||||||
# TODO : also, there should be a form of cache that allows this to be more efficient
|
# TODO : also, there should be a form of cache that allows this to be more efficient
|
||||||
category =
|
|
||||||
if is_nil(ical_event.categories) do
|
|
||||||
nil
|
|
||||||
else
|
|
||||||
ical_category = ical_event.categories |> hd() |> String.downcase()
|
|
||||||
|
|
||||||
case ical_category |> Events.get_category_by_title() do
|
# ical_event.categories should be tags
|
||||||
nil ->
|
|
||||||
case Events.create_category(%{"title" => ical_category}) do
|
|
||||||
{:ok, %Category{} = category} -> category
|
|
||||||
_ -> nil
|
|
||||||
end
|
|
||||||
|
|
||||||
category ->
|
|
||||||
category
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
{:ok, event} =
|
{:ok, event} =
|
||||||
Events.create_event(%{
|
Events.create_event(%{
|
||||||
|
@ -591,8 +576,7 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||||
updated_at: ical_event.stamp,
|
updated_at: ical_event.stamp,
|
||||||
description: ical_event.description |> sanitize_ical_event_strings,
|
description: ical_event.description |> sanitize_ical_event_strings,
|
||||||
title: ical_event.summary |> sanitize_ical_event_strings,
|
title: ical_event.summary |> sanitize_ical_event_strings,
|
||||||
organizer_actor: actor,
|
organizer_actor: actor
|
||||||
category: category
|
|
||||||
})
|
})
|
||||||
|
|
||||||
event_to_activity(event, false)
|
event_to_activity(event, false)
|
||||||
|
|
|
@ -117,7 +117,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
|
||||||
"description" => object["content"],
|
"description" => object["content"],
|
||||||
"organizer_actor_id" => actor_id,
|
"organizer_actor_id" => actor_id,
|
||||||
"begins_on" => object["begins_on"],
|
"begins_on" => object["begins_on"],
|
||||||
"category_id" => Events.get_category_by_title(object["category"]).id,
|
"category" => object["category"],
|
||||||
"url" => object["id"],
|
"url" => object["id"],
|
||||||
"uuid" => object["uuid"]
|
"uuid" => object["uuid"]
|
||||||
}
|
}
|
||||||
|
|
35
priv/repo/migrations/20190222151449_drop_categories.exs
Normal file
35
priv/repo/migrations/20190222151449_drop_categories.exs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
defmodule Mobilizon.Repo.Migrations.DropCategories do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
# The category field is a string for the time being
|
||||||
|
# while we determine the definitive minimal list of
|
||||||
|
# categories in https://framagit.org/framasoft/mobilizon/issues/30
|
||||||
|
# afterwards it will be a PostgreSQL enum and we'll
|
||||||
|
# just add new elements without being able to delete
|
||||||
|
# the previous ones
|
||||||
|
alter table(:events) do
|
||||||
|
add(:category, :string)
|
||||||
|
remove(:category_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
drop(table(:categories))
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
create table(:categories) do
|
||||||
|
add(:title, :string)
|
||||||
|
add(:description, :string)
|
||||||
|
add(:picture, :string)
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
create(unique_index(:categories, [:title]))
|
||||||
|
|
||||||
|
alter table(:events) do
|
||||||
|
remove(:category)
|
||||||
|
add(:category_id, references(:categories, on_delete: :nothing))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,8 @@ defmodule Mobilizon.EventsTest do
|
||||||
ends_on: "2010-04-17 14:00:00Z",
|
ends_on: "2010-04-17 14:00:00Z",
|
||||||
title: "some title",
|
title: "some title",
|
||||||
url: "some url",
|
url: "some url",
|
||||||
uuid: "b5126423-f1af-43e4-a923-002a03003ba4"
|
uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
|
||||||
|
category: "meeting"
|
||||||
}
|
}
|
||||||
|
|
||||||
describe "events" do
|
describe "events" do
|
||||||
|
@ -79,14 +80,12 @@ defmodule Mobilizon.EventsTest do
|
||||||
|
|
||||||
test "create_event/1 with valid data creates a event" do
|
test "create_event/1 with valid data creates a event" do
|
||||||
actor = insert(:actor)
|
actor = insert(:actor)
|
||||||
category = insert(:category)
|
|
||||||
address = insert(:address)
|
address = insert(:address)
|
||||||
|
|
||||||
valid_attrs =
|
valid_attrs =
|
||||||
@event_valid_attrs
|
@event_valid_attrs
|
||||||
|> Map.put(:organizer_actor, actor)
|
|> Map.put(:organizer_actor, actor)
|
||||||
|> Map.put(:organizer_actor_id, actor.id)
|
|> Map.put(:organizer_actor_id, actor.id)
|
||||||
|> Map.put(:category_id, category.id)
|
|
||||||
|> Map.put(:address_id, address.id)
|
|> Map.put(:address_id, address.id)
|
||||||
|
|
||||||
with {:ok, %Event{} = event} <- Events.create_event(valid_attrs) do
|
with {:ok, %Event{} = event} <- Events.create_event(valid_attrs) do
|
||||||
|
@ -175,77 +174,6 @@ defmodule Mobilizon.EventsTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "categories" do
|
|
||||||
alias Mobilizon.Events.Category
|
|
||||||
|
|
||||||
setup do
|
|
||||||
category = insert(:category)
|
|
||||||
{:ok, category: category}
|
|
||||||
end
|
|
||||||
|
|
||||||
@valid_attrs %{
|
|
||||||
description: "some description",
|
|
||||||
picture: %Plug.Upload{
|
|
||||||
path: "test/fixtures/category_picture.png",
|
|
||||||
filename: "category_picture.png"
|
|
||||||
},
|
|
||||||
title: "some title"
|
|
||||||
}
|
|
||||||
@update_attrs %{
|
|
||||||
description: "some updated description",
|
|
||||||
picture: %Plug.Upload{
|
|
||||||
path: "test/fixtures/category_picture_updated.png",
|
|
||||||
filename: "category_picture_updated.png"
|
|
||||||
},
|
|
||||||
title: "some updated title"
|
|
||||||
}
|
|
||||||
@invalid_attrs %{description: nil, picture: nil, title: nil}
|
|
||||||
|
|
||||||
test "list_categories/0 returns all categories", %{category: category} do
|
|
||||||
assert [category.id] == Events.list_categories() |> Enum.map(& &1.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "get_category!/1 returns the category with given id", %{category: category} do
|
|
||||||
assert Events.get_category!(category.id).id == category.id
|
|
||||||
end
|
|
||||||
|
|
||||||
test "get_category_by_title/1 return the category with given title", %{category: category} do
|
|
||||||
assert Events.get_category_by_title(category.title).id == category.id
|
|
||||||
end
|
|
||||||
|
|
||||||
test "create_category/1 with valid data creates a category" do
|
|
||||||
assert {:ok, %Category{} = category} = Events.create_category(@valid_attrs)
|
|
||||||
assert category.description == "some description"
|
|
||||||
assert category.picture.file_name == @valid_attrs.picture.filename
|
|
||||||
assert category.title == "some title"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "create_category/1 with invalid data returns error changeset" do
|
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.create_category(@invalid_attrs)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "update_category/2 with valid data updates the category", %{category: category} do
|
|
||||||
assert {:ok, %Category{} = category} = Events.update_category(category, @update_attrs)
|
|
||||||
assert category.description == "some updated description"
|
|
||||||
assert category.picture.file_name == @update_attrs.picture.filename
|
|
||||||
assert category.title == "some updated title"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "update_category/2 with invalid data returns error changeset", %{category: category} do
|
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.update_category(category, @invalid_attrs)
|
|
||||||
assert category.description == Events.get_category!(category.id).description
|
|
||||||
end
|
|
||||||
|
|
||||||
test "delete_category/1 deletes the category", %{category: category} do
|
|
||||||
assert {:ok, %Category{}} = Events.delete_category(category)
|
|
||||||
assert_raise Ecto.NoResultsError, fn -> Events.get_category!(category.id) end
|
|
||||||
end
|
|
||||||
|
|
||||||
test "change_category/1 returns a category changeset", %{category: category} do
|
|
||||||
assert %Ecto.Changeset{} = Events.change_category(category)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "tags" do
|
describe "tags" do
|
||||||
alias Mobilizon.Events.Tag
|
alias Mobilizon.Events.Tag
|
||||||
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
defmodule MobilizonWeb.Resolvers.CategoryResolverTest do
|
|
||||||
use MobilizonWeb.ConnCase
|
|
||||||
alias MobilizonWeb.AbsintheHelpers
|
|
||||||
import Mobilizon.Factory
|
|
||||||
|
|
||||||
setup %{conn: conn} do
|
|
||||||
user = insert(:user)
|
|
||||||
actor = insert(:actor, user: user)
|
|
||||||
|
|
||||||
{:ok, conn: conn, actor: actor, user: user}
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "Category Resolver" do
|
|
||||||
test "list_categories/3 returns the list of categories", context do
|
|
||||||
insert(:category)
|
|
||||||
insert(:category)
|
|
||||||
|
|
||||||
query = """
|
|
||||||
{
|
|
||||||
categories {
|
|
||||||
id,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
picture {
|
|
||||||
url,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
res =
|
|
||||||
context.conn
|
|
||||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "categories"))
|
|
||||||
|
|
||||||
assert json_response(res, 200)["data"]["categories"] |> length == 2
|
|
||||||
end
|
|
||||||
|
|
||||||
# We can't test an upload…yet?
|
|
||||||
# test "create_category/3 creates a category", %{conn: conn, actor: actor, user: user} do
|
|
||||||
# mutation = """
|
|
||||||
# mutation {
|
|
||||||
# createCategory(title: "my category", description: "my desc") {
|
|
||||||
# id,
|
|
||||||
# title,
|
|
||||||
# description,
|
|
||||||
# },
|
|
||||||
# }
|
|
||||||
# """
|
|
||||||
|
|
||||||
# res =
|
|
||||||
# conn
|
|
||||||
# |> auth_conn(user)
|
|
||||||
# |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
|
|
||||||
|
|
||||||
# assert json_response(res, 200)["data"]["createCategory"]["title"] == "my category"
|
|
||||||
# end
|
|
||||||
|
|
||||||
# test "create_category/3 doesn't create a category if the user isn't logged in", %{conn: conn, actor: actor} do
|
|
||||||
# mutation = """
|
|
||||||
# mutation {
|
|
||||||
# createCategory(title: "my category", description: "my desc") {
|
|
||||||
# id,
|
|
||||||
# title,
|
|
||||||
# description,
|
|
||||||
# },
|
|
||||||
# }
|
|
||||||
# """
|
|
||||||
|
|
||||||
# res =
|
|
||||||
# conn
|
|
||||||
# |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
|
|
||||||
|
|
||||||
# assert hd(json_response(res, 200)["errors"])["message"] ==
|
|
||||||
# "You are not allowed to create a category if not connected"
|
|
||||||
# end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -9,7 +9,8 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
|
||||||
title: "some title",
|
title: "some title",
|
||||||
begins_on: DateTime.utc_now() |> DateTime.truncate(:second),
|
begins_on: DateTime.utc_now() |> DateTime.truncate(:second),
|
||||||
uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
|
uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
|
||||||
url: "some url"
|
url: "some url",
|
||||||
|
category: "meeting"
|
||||||
}
|
}
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
|
@ -21,12 +22,9 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
|
||||||
|
|
||||||
describe "Event Resolver" do
|
describe "Event Resolver" do
|
||||||
test "find_event/3 returns an event", context do
|
test "find_event/3 returns an event", context do
|
||||||
category = insert(:category)
|
|
||||||
|
|
||||||
event =
|
event =
|
||||||
@event
|
@event
|
||||||
|> Map.put(:organizer_actor_id, context.actor.id)
|
|> Map.put(:organizer_actor_id, context.actor.id)
|
||||||
|> Map.put(:category_id, category.id)
|
|
||||||
|
|
||||||
{:ok, event} = Events.create_event(event)
|
{:ok, event} = Events.create_event(event)
|
||||||
|
|
||||||
|
@ -61,8 +59,6 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_event/3 creates an event", %{conn: conn, actor: actor, user: user} do
|
test "create_event/3 creates an event", %{conn: conn, actor: actor, user: user} do
|
||||||
category = insert(:category)
|
|
||||||
|
|
||||||
mutation = """
|
mutation = """
|
||||||
mutation {
|
mutation {
|
||||||
createEvent(
|
createEvent(
|
||||||
|
@ -72,7 +68,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
|
||||||
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
|
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
|
||||||
}",
|
}",
|
||||||
organizer_actor_id: "#{actor.id}",
|
organizer_actor_id: "#{actor.id}",
|
||||||
category: "#{category.title}"
|
category: "birthday"
|
||||||
) {
|
) {
|
||||||
title,
|
title,
|
||||||
uuid
|
uuid
|
||||||
|
|
|
@ -9,7 +9,8 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
|
||||||
title: "some title",
|
title: "some title",
|
||||||
begins_on: DateTime.utc_now() |> DateTime.truncate(:second),
|
begins_on: DateTime.utc_now() |> DateTime.truncate(:second),
|
||||||
uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
|
uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
|
||||||
url: "some url"
|
url: "some url",
|
||||||
|
category: "meeting"
|
||||||
}
|
}
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
|
@ -313,13 +314,9 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "list_participants_for_event/3 returns participants for an event", context do
|
test "list_participants_for_event/3 returns participants for an event", context do
|
||||||
# Plain event
|
|
||||||
category = insert(:category)
|
|
||||||
|
|
||||||
event =
|
event =
|
||||||
@event
|
@event
|
||||||
|> Map.put(:organizer_actor_id, context.actor.id)
|
|> Map.put(:organizer_actor_id, context.actor.id)
|
||||||
|> Map.put(:category_id, category.id)
|
|
||||||
|
|
||||||
{:ok, event} = Events.create_event(event)
|
{:ok, event} = Events.create_event(event)
|
||||||
|
|
||||||
|
|
|
@ -53,13 +53,6 @@ defmodule Mobilizon.Factory do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def category_factory do
|
|
||||||
%Mobilizon.Events.Category{
|
|
||||||
title: sequence("MyCategory"),
|
|
||||||
description: "My category desc"
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def tag_factory do
|
def tag_factory do
|
||||||
%Mobilizon.Events.Tag{
|
%Mobilizon.Events.Tag{
|
||||||
title: "MyTag",
|
title: "MyTag",
|
||||||
|
@ -112,7 +105,7 @@ defmodule Mobilizon.Factory do
|
||||||
begins_on: start,
|
begins_on: start,
|
||||||
ends_on: Timex.shift(start, hours: 2),
|
ends_on: Timex.shift(start, hours: 2),
|
||||||
organizer_actor: actor,
|
organizer_actor: actor,
|
||||||
category: build(:category),
|
category: sequence("something"),
|
||||||
physical_address: build(:address),
|
physical_address: build(:address),
|
||||||
visibility: :public,
|
visibility: :public,
|
||||||
url: "#{actor.url}/#{uuid}",
|
url: "#{actor.url}/#{uuid}",
|
||||||
|
|
Loading…
Reference in a new issue