Merge branch 'docker' into 'master'
Docker See merge request tcit/eventos!16
This commit is contained in:
commit
64245aaf32
11
Dockerfile
Normal file
11
Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
FROM elixir:1.6
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y build-essential inotify-tools postgresql-client
|
||||||
|
|
||||||
|
RUN mix local.hex --force && mix local.rebar --force
|
||||||
|
|
||||||
|
COPY docker/entrypoint.sh /bin/entrypoint
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
EXPOSE 4000
|
|
@ -47,15 +47,14 @@ config :logger, :console, format: "[$level] $message\n", level: :debug
|
||||||
# in production as building large stacktraces may be expensive.
|
# in production as building large stacktraces may be expensive.
|
||||||
config :phoenix, :stacktrace_depth, 20
|
config :phoenix, :stacktrace_depth, 20
|
||||||
|
|
||||||
config :eventos, Eventos.Mailer,
|
config :eventos, Eventos.Mailer, adapter: Bamboo.LocalAdapter
|
||||||
adapter: Bamboo.LocalAdapter
|
|
||||||
|
|
||||||
# Configure your database
|
# Configure your database
|
||||||
config :eventos, Eventos.Repo,
|
config :eventos, Eventos.Repo,
|
||||||
adapter: Ecto.Adapters.Postgres,
|
adapter: Ecto.Adapters.Postgres,
|
||||||
types: Eventos.PostgresTypes,
|
types: Eventos.PostgresTypes,
|
||||||
username: "elixir",
|
username: System.get_env("POSTGRES_USER") || "elixir",
|
||||||
password: "elixir",
|
password: System.get_env("POSTGRES_PASSWORD") || "elixir",
|
||||||
database: "eventos_dev",
|
database: System.get_env("POSTGRES_DATABASE") || "eventos_dev",
|
||||||
hostname: "localhost",
|
hostname: System.get_env("POSTGRES_HOST") || "localhost",
|
||||||
pool_size: 10
|
pool_size: 10
|
||||||
|
|
38
docker-compose.yml
Normal file
38
docker-compose.yml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
container_name: eventos_db
|
||||||
|
restart: unless-stopped
|
||||||
|
image: mdillon/postgis:10
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
POSTGRES_DB: eventos_dev
|
||||||
|
|
||||||
|
front:
|
||||||
|
container_name: eventos_front
|
||||||
|
restart: unless-stopped
|
||||||
|
build: ./js
|
||||||
|
volumes:
|
||||||
|
- './js:/app/js'
|
||||||
|
ports:
|
||||||
|
- "80:8080"
|
||||||
|
entrypoint: entrypoint
|
||||||
|
|
||||||
|
api:
|
||||||
|
container_name: eventos_api
|
||||||
|
restart: unless-stopped
|
||||||
|
build: .
|
||||||
|
volumes:
|
||||||
|
- '.:/app'
|
||||||
|
ports:
|
||||||
|
- "4000:4000"
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_DATABASE: eventos_dev
|
||||||
|
POSTGRES_HOST: postgres
|
||||||
|
entrypoint: entrypoint
|
22
docker/entrypoint.sh
Executable file
22
docker/entrypoint.sh
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mix deps.get
|
||||||
|
|
||||||
|
# Wait for Postgres to become available.
|
||||||
|
until PGPASSWORD=$POSTGRES_PASSWORD psql -h postgres -U "postgres" -c '\q' 2>/dev/null; do
|
||||||
|
>&2 echo "Postgres is unavailable - sleeping"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "\nPostgres is available: continuing with database setup..."
|
||||||
|
|
||||||
|
# Potentially Set up the database
|
||||||
|
mix ecto.create
|
||||||
|
mix ecto.migrate
|
||||||
|
|
||||||
|
echo "\nTesting the installation..."
|
||||||
|
# "Proove" that install was successful by running the tests
|
||||||
|
mix test
|
||||||
|
|
||||||
|
echo "\n Launching Phoenix web server..."
|
||||||
|
iex -S mix phx.server
|
9
js/Dockerfile
Normal file
9
js/Dockerfile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
FROM node:10
|
||||||
|
|
||||||
|
LABEL maintainer="tcit"
|
||||||
|
|
||||||
|
COPY docker/entrypoint.sh /bin/entrypoint
|
||||||
|
|
||||||
|
WORKDIR /app/js
|
||||||
|
|
||||||
|
EXPOSE 8080
|
5
js/docker/entrypoint.sh
Executable file
5
js/docker/entrypoint.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
npm install
|
||||||
|
npm rebuild node-sass
|
||||||
|
npm run serve
|
|
@ -9,22 +9,48 @@
|
||||||
enable-resize-watcher
|
enable-resize-watcher
|
||||||
>
|
>
|
||||||
<v-list dense>
|
<v-list dense>
|
||||||
<v-list-tile avatar v-if="$store.state.user">
|
<v-list-group
|
||||||
<v-list-tile-avatar>
|
value="false"
|
||||||
<img v-if="!getUser().actor.avatar_url"
|
>
|
||||||
class="img-circle elevation-7 mb-1"
|
<v-list-tile avatar v-if="$store.state.actor" slot="activator">
|
||||||
src="https://picsum.photos/125/125/"
|
<v-list-tile-avatar>
|
||||||
>
|
<img v-if="!$store.state.actor.avatar"
|
||||||
<img v-else
|
class="img-circle elevation-7 mb-1"
|
||||||
class="img-circle elevation-7 mb-1"
|
src="https://picsum.photos/125/125/"
|
||||||
:src="getUser().actor.avatar_url"
|
>
|
||||||
>
|
<img v-else
|
||||||
</v-list-tile-avatar>
|
class="img-circle elevation-7 mb-1"
|
||||||
|
:src="$store.state.actor.avatar"
|
||||||
|
>
|
||||||
|
</v-list-tile-avatar>
|
||||||
|
|
||||||
<v-list-tile-content @click="$router.push({name: 'Account', params: { name: getUser().actor.username }})">
|
<v-list-tile-content @click="$router.push({name: 'Account', params: { name: $store.state.actor.username }})">
|
||||||
<v-list-tile-title>{{ this.displayed_name }}</v-list-tile-title>
|
<v-list-tile-title>{{ this.displayed_name }}</v-list-tile-title>
|
||||||
</v-list-tile-content>
|
</v-list-tile-content>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
|
|
||||||
|
<v-list-tile avatar v-if="$store.state.actor">
|
||||||
|
<v-list-tile-avatar>
|
||||||
|
<img
|
||||||
|
class="img-circle elevation-7 mb-1"
|
||||||
|
src="https://picsum.photos/125/125/"
|
||||||
|
>
|
||||||
|
</v-list-tile-avatar>
|
||||||
|
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Autre identité</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
|
<v-list-tile @click="$router.push({ name: 'Identities' })">
|
||||||
|
<v-list-tile-action>
|
||||||
|
<v-icon>group</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Identities</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
</v-list-tile>
|
||||||
|
</v-list-group>
|
||||||
<template v-for="(item, i) in items" v-if="showMenuItem(item.role)">
|
<template v-for="(item, i) in items" v-if="showMenuItem(item.role)">
|
||||||
<v-layout
|
<v-layout
|
||||||
row
|
row
|
||||||
|
@ -160,7 +186,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
displayed_name() {
|
displayed_name() {
|
||||||
return this.$store.state.user.actor.display_name === null ? this.$store.state.user.actor.username : this.$store.state.user.actor.display_name
|
return this.$store.state.actor.display_name === null ? this.$store.state.actor.username : this.$store.state.actor.display_name
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { API_ORIGIN, API_PATH } from '../api/_entrypoint';
|
import { API_ORIGIN, API_PATH } from '../api/_entrypoint';
|
||||||
|
import { LOGIN_USER, LOAD_USER, CHANGE_ACTOR } from '../store/mutation-types';
|
||||||
|
|
||||||
// URL and endpoint constants
|
// URL and endpoint constants
|
||||||
const LOGIN_URL = `${API_ORIGIN}${API_PATH}/login`;
|
const LOGIN_URL = `${API_ORIGIN}${API_PATH}/login`;
|
||||||
|
@ -53,7 +54,7 @@ export default {
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log('We have a new token');
|
console.log('We have a new token');
|
||||||
this.authenticated = true;
|
this.authenticated = true;
|
||||||
store.commit('LOGIN_USER', response);
|
store.commit(LOGIN_USER, response);
|
||||||
localStorage.setItem('token', response.token);
|
localStorage.setItem('token', response.token);
|
||||||
console.log("Let's try to auth again");
|
console.log("Let's try to auth again");
|
||||||
successHandler();
|
successHandler();
|
||||||
|
@ -104,9 +105,10 @@ export default {
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
this.authenticated = true;
|
this.authenticated = true;
|
||||||
console.log(response);
|
console.log(response);
|
||||||
store.commit('LOAD_USER', response.data);
|
store.commit(LOAD_USER, response.data);
|
||||||
|
store.commit(CHANGE_ACTOR, response.data.actors[0]);
|
||||||
return successHandler();
|
return successHandler();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// The object to be passed as a header for authenticated requests
|
// The object to be passed as a header for authenticated requests
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<v-icon>chevron_left</v-icon>
|
<v-icon>chevron_left</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn icon class="mr-3" v-if="$store.state.user && $store.state.user.actor.id === actor.id">
|
<v-btn icon class="mr-3" v-if="$store.state.user && $store.state.actor.id === actor.id">
|
||||||
<v-icon>edit</v-icon>
|
<v-icon>edit</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-menu bottom left>
|
<v-menu bottom left>
|
||||||
|
@ -18,10 +18,10 @@
|
||||||
<v-icon>more_vert</v-icon>
|
<v-icon>more_vert</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-tile @click="logoutUser()" v-if="$store.state.user && $store.state.user.actor.id === actor.id">
|
<v-list-tile @click="logoutUser()" v-if="$store.state.user && $store.state.actor.id === actor.id">
|
||||||
<v-list-tile-title>User logout</v-list-tile-title>
|
<v-list-tile-title>User logout</v-list-tile-title>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
<v-list-tile @click="deleteAccount()" v-if="$store.state.user && $store.state.user.actor.id === actor.id">
|
<v-list-tile @click="deleteAccount()" v-if="$store.state.user && $store.state.actor.id === actor.id">
|
||||||
<v-list-tile-title>Delete</v-list-tile-title>
|
<v-list-tile-title>Delete</v-list-tile-title>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
</v-list>
|
</v-list>
|
||||||
|
@ -30,13 +30,13 @@
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<div class="text-xs-center">
|
<div class="text-xs-center">
|
||||||
<v-avatar size="125px">
|
<v-avatar size="125px">
|
||||||
<img v-if="!actor.avatar_url"
|
<img v-if="!actor.avatar"
|
||||||
class="img-circle elevation-7 mb-1"
|
class="img-circle elevation-7 mb-1"
|
||||||
src="https://picsum.photos/125/125/"
|
src="https://picsum.photos/125/125/"
|
||||||
>
|
>
|
||||||
<img v-else
|
<img v-else
|
||||||
class="img-circle elevation-7 mb-1"
|
class="img-circle elevation-7 mb-1"
|
||||||
:src="actor.avatar_url"
|
:src="actor.avatar"
|
||||||
>
|
>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
</div>
|
</div>
|
||||||
|
|
132
js/src/components/Account/Identities.vue
Normal file
132
js/src/components/Account/Identities.vue
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
<template>
|
||||||
|
<v-layout row>
|
||||||
|
<v-flex xs12 sm6 offset-sm3>
|
||||||
|
<v-progress-circular v-if="loading" indeterminate color="primary"></v-progress-circular>
|
||||||
|
<v-card v-if="!loading">
|
||||||
|
<v-toolbar dark color="primary">
|
||||||
|
<v-toolbar-title>Identities</v-toolbar-title>
|
||||||
|
</v-toolbar>
|
||||||
|
<v-card-text>
|
||||||
|
<v-list two-line>
|
||||||
|
<v-list-tile
|
||||||
|
v-for="actor in actors"
|
||||||
|
:key="actor.id"
|
||||||
|
avatar
|
||||||
|
@click="$router.push({ name: 'Account', params: { name: actor.username } })"
|
||||||
|
>
|
||||||
|
<v-list-tile-action>
|
||||||
|
<v-icon v-if="$store.state.defaultActor === actor.username" color="pink">star</v-icon>
|
||||||
|
</v-list-tile-action>
|
||||||
|
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title v-text="actor.username"></v-list-tile-title>
|
||||||
|
<v-list-tile-sub-title v-if="actor.display_name" v-text="actor.display_name"></v-list-tile-sub-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
|
||||||
|
<v-list-tile-avatar>
|
||||||
|
<img :src="actor.avatar">
|
||||||
|
</v-list-tile-avatar>
|
||||||
|
</v-list-tile>
|
||||||
|
</v-list>
|
||||||
|
<v-divider v-if="showForm"></v-divider>
|
||||||
|
<v-form v-if="showForm">
|
||||||
|
<v-text-field
|
||||||
|
label="Username"
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
v-model="newActor.preferred_username"
|
||||||
|
:rules="[rules.required]"
|
||||||
|
:error="this.state.username.status"
|
||||||
|
:error-messages="this.state.username.msg"
|
||||||
|
:suffix="this.host()"
|
||||||
|
hint="You will be able to create more identities once registered"
|
||||||
|
persistent-hint
|
||||||
|
>
|
||||||
|
</v-text-field>
|
||||||
|
<v-textarea
|
||||||
|
name="input-7-1"
|
||||||
|
label="Profile description"
|
||||||
|
hint="Will be displayed publicly on your profile"
|
||||||
|
></v-textarea>
|
||||||
|
</v-form>
|
||||||
|
<v-btn
|
||||||
|
color="pink"
|
||||||
|
dark
|
||||||
|
absolute
|
||||||
|
bottom
|
||||||
|
right
|
||||||
|
fab
|
||||||
|
@click="toggleForm()"
|
||||||
|
>
|
||||||
|
<v-icon>{{ showForm ? 'check' : 'add' }}</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import eventFetch from "@/api/eventFetch";
|
||||||
|
import auth from "@/auth";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Identities",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
actors: [],
|
||||||
|
newActor: {
|
||||||
|
preferred_username: "",
|
||||||
|
summary: ""
|
||||||
|
},
|
||||||
|
loading: true,
|
||||||
|
showForm: false,
|
||||||
|
rules: {
|
||||||
|
required: value => !!value || "Required."
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
username: {
|
||||||
|
status: false,
|
||||||
|
msg: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.fetchData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchData() {
|
||||||
|
eventFetch(`/user`, this.$store)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
this.actors = response.data.actors;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
sendData() {
|
||||||
|
this.loading = true;
|
||||||
|
this.showForm = false;
|
||||||
|
eventFetch(`/actors`, this.$store, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ actor: this.newActor })
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
this.actors.push(response.data);
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toggleForm() {
|
||||||
|
if (this.showForm === true) {
|
||||||
|
this.sendData();
|
||||||
|
} else {
|
||||||
|
this.showForm = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
host() {
|
||||||
|
return `@${window.location.host}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -60,6 +60,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
import { LOGIN_USER } from '@/store/mutation-types';
|
||||||
import auth from '@/auth/index';
|
import auth from '@/auth/index';
|
||||||
import Gravatar from 'vue-gravatar';
|
import Gravatar from 'vue-gravatar';
|
||||||
import RegisterAvatar from './RegisterAvatar';
|
import RegisterAvatar from './RegisterAvatar';
|
||||||
|
@ -119,7 +120,7 @@
|
||||||
loginAction(e) {
|
loginAction(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
auth.login(JSON.stringify(this.credentials), (data) => {
|
auth.login(JSON.stringify(this.credentials), (data) => {
|
||||||
this.$store.commit('LOGIN_USER', data.user);
|
this.$store.commit(LOGIN_USER, data.user);
|
||||||
this.$router.push({ name: 'Home' });
|
this.$router.push({ name: 'Home' });
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
Promise.resolve(error).then((errorMsg) => {
|
Promise.resolve(error).then((errorMsg) => {
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<b-container>
|
<v-container>
|
||||||
<h1 v-if="loading">{{ $t('registration.validation.process') }}</h1>
|
<h1 v-if="loading">{{ $t('registration.validation.process') }}</h1>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div v-if="failed">
|
<div v-if="failed">
|
||||||
<b-alert show variant="danger">{{ $t('registration.success.validation_failure') }}</b-alert>
|
<v-alert :value="true" variant="danger">Error while validating account</v-alert>
|
||||||
</div>
|
</div>
|
||||||
<h1 v-else>{{ $t('registration.validation.finished') }}</h1>
|
<h1 v-else>{{ $t('registration.validation.finished') }}</h1>
|
||||||
</div>
|
</div>
|
||||||
</b-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import fetchStory from '@/api/eventFetch';
|
import fetchStory from '@/api/eventFetch';
|
||||||
|
import { LOGIN_USER } from '@/store/mutation-types';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Validate',
|
name: 'Validate',
|
||||||
|
@ -36,7 +37,7 @@ export default {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
localStorage.setItem('token', data.token);
|
localStorage.setItem('token', data.token);
|
||||||
localStorage.setItem('refresh_token', data.refresh_token);
|
localStorage.setItem('refresh_token', data.refresh_token);
|
||||||
this.$store.commit('LOGIN_USER', data.account);
|
this.$store.commit(LOGIN_USER, data.account);
|
||||||
this.$snotify.success(this.$t('registration.success.login', { username: data.account.username }));
|
this.$snotify.success(this.$t('registration.success.login', { username: data.account.username }));
|
||||||
this.$router.push({ name: 'Home' });
|
this.$router.push({ name: 'Home' });
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
|
|
@ -120,8 +120,8 @@
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
this.event.category_id = this.event.category;
|
this.event.category_id = this.event.category;
|
||||||
this.event.organizer_actor_id = this.$store.state.user.actor.id;
|
this.event.organizer_actor_id = this.$store.state.actor.id;
|
||||||
this.event.participants = [this.$store.state.user.actor.id];
|
this.event.participants = [this.$store.state.actor.id];
|
||||||
// this.event.price = parseFloat(this.event.price);
|
// this.event.price = parseFloat(this.event.price);
|
||||||
|
|
||||||
if (this.id === undefined) {
|
if (this.id === undefined) {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<v-icon>chevron_left</v-icon>
|
<v-icon>chevron_left</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn icon class="mr-3 white--text" v-if="event.organizer.id === $store.state.user.actor.id" :to="{ name: 'EditEvent', params: {id: event.id}}">
|
<v-btn icon class="mr-3 white--text" v-if="actorIsOrganizer()" :to="{ name: 'EditEvent', params: {id: event.id}}">
|
||||||
<v-icon>edit</v-icon>
|
<v-icon>edit</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-menu bottom left>
|
<v-menu bottom left>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<v-list-tile @click="downloadIcsEvent()">
|
<v-list-tile @click="downloadIcsEvent()">
|
||||||
<v-list-tile-title>Download</v-list-tile-title>
|
<v-list-tile-title>Download</v-list-tile-title>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
<v-list-tile @click="deleteEvent()" v-if="$store.state.user.actor.id === event.organizer.id">
|
<v-list-tile @click="deleteEvent()" v-if="actorIsOrganizer()">
|
||||||
<v-list-tile-title>Delete</v-list-tile-title>
|
<v-list-tile-title>Delete</v-list-tile-title>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
</v-list>
|
</v-list>
|
||||||
|
@ -217,10 +217,10 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
actorIsParticipant() {
|
actorIsParticipant() {
|
||||||
return this.event.participants.map(participant => participant.id).includes(this.$store.state.user.actor.id) || this.actorIsOrganizer();
|
return this.$store.state.actor && this.event.participants.map(participant => participant.id).includes(this.$store.state.actor.id) || this.actorIsOrganizer();
|
||||||
},
|
},
|
||||||
actorIsOrganizer() {
|
actorIsOrganizer() {
|
||||||
return this.$store.state.user.actor.id === this.event.organizer.id;
|
return this.$store.state.actor && this.$store.state.actor.id === this.event.organizer.id;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<v-icon>chevron_left</v-icon>
|
<v-icon>chevron_left</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<!--<v-btn icon class="mr-3" v-if="$store.state.user && $store.state.user.actor.id === actor.id">-->
|
<!--<v-btn icon class="mr-3" v-if="$store.state.user && $store.state.actor.id === actor.id">-->
|
||||||
<!--<v-icon>edit</v-icon>-->
|
<!--<v-icon>edit</v-icon>-->
|
||||||
<!--</v-btn>-->
|
<!--</v-btn>-->
|
||||||
<v-btn icon>
|
<v-btn icon>
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-jumbotron>
|
</v-jumbotron>
|
||||||
<v-layout>
|
<v-layout v-else>
|
||||||
<v-flex xs12 sm8 offset-sm2>
|
<v-flex xs12 sm8 offset-sm2>
|
||||||
<v-layout row wrap>
|
<v-layout row wrap>
|
||||||
<v-flex xs12 sm6>
|
<v-flex xs12 sm6>
|
||||||
<h1>Welcome back {{ $store.state.user.actor.username }}</h1>
|
<h1>Welcome back {{ $store.state.actor.username }}</h1>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 sm6>
|
<v-flex xs12 sm6>
|
||||||
<v-layout align-center>
|
<v-layout align-center>
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
</v-card-media>
|
</v-card-media>
|
||||||
<v-card-title primary-title>
|
<v-card-title primary-title>
|
||||||
<div>
|
<div>
|
||||||
<span class="grey--text">{{ event.begins_on | formatDate }}</span><br>
|
<span class="grey--text">{{ event.begins_on | formatDay }}</span><br>
|
||||||
<router-link :to="{name: 'Account', params: { name: event.organizer.username } }">
|
<router-link :to="{name: 'Account', params: { name: event.organizer.username } }">
|
||||||
<v-avatar size="25px">
|
<v-avatar size="25px">
|
||||||
<img class="img-circle elevation-7 mb-1"
|
<img class="img-circle elevation-7 mb-1"
|
||||||
|
@ -100,8 +100,8 @@ export default {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
displayed_name: function() {
|
displayed_name() {
|
||||||
return this.$store.state.user.actor.display_name === null ? this.$store.state.user.actor.username : this.$store.state.user.actor.display_name
|
return this.$store.state.actor.display_name === null ? this.$store.state.actor.username : this.$store.state.actor.display_name
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -75,8 +75,7 @@
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
<v-btn flat @click="$router.push({name: 'Account', params: { name: getUser().actor.username }})" v-if="$store.state.user">{{ this.displayed_name }}</v-btn>
|
<v-btn v-if="!$store.state.user" :to="{ name: 'Login' }">Se connecter</v-btn>
|
||||||
<v-btn v-else :to="{ name: 'Login' }">Se connecter</v-btn>
|
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -123,7 +122,10 @@
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
displayed_name: function() {
|
displayed_name: function() {
|
||||||
return this.$store.state.user.actor.display_name === null ? this.$store.state.user.actor.username : this.$store.state.user.actor.display_name
|
console.log('displayed name', this.$store.state.actor);
|
||||||
|
if (this.$store.state.actor) {
|
||||||
|
return this.$store.state.actor.display_name === null ? this.$store.state.actor.username : this.$store.state.actor.display_name;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -3,36 +3,21 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
// import * as VueGoogleMaps from 'vue2-google-maps';
|
// import * as VueGoogleMaps from 'vue2-google-maps';
|
||||||
import VueMarkdown from 'vue-markdown';
|
import VueMarkdown from 'vue-markdown';
|
||||||
import VuetifyGoogleAutocomplete from 'vuetify-google-autocomplete';
|
|
||||||
import Vuetify from 'vuetify';
|
import Vuetify from 'vuetify';
|
||||||
import Vuex from 'vuex';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import VuexI18n from 'vuex-i18n';
|
import VuexI18n from 'vuex-i18n';
|
||||||
import 'material-design-icons/iconfont/material-icons.css';
|
import 'material-design-icons/iconfont/material-icons.css';
|
||||||
import 'vuetify/dist/vuetify.min.css';
|
import 'vuetify/dist/vuetify.min.css';
|
||||||
import App from '@/App';
|
import App from './App.vue';
|
||||||
import router from '@/router';
|
import router from './router';
|
||||||
import storeData from '@/store/index';
|
import store from './store';
|
||||||
import translations from '@/i18n/index';
|
import translations from './i18n';
|
||||||
import auth from '@/auth';
|
import auth from './auth';
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
Vue.use(VuetifyGoogleAutocomplete, {
|
|
||||||
apiKey: 'AIzaSyBF37pw38j0giICt73TCAPNogc07Upe_Q4', // Can also be an object. E.g, for Google Maps Premium API, pass `{ client: <YOUR-CLIENT-ID> }`
|
|
||||||
});
|
|
||||||
|
|
||||||
/*Vue.use(VueGoogleMaps, {
|
|
||||||
load: {
|
|
||||||
key: 'AIzaSyBF37pw38j0giICt73TCAPNogc07Upe_Q4',
|
|
||||||
libraries: 'places',
|
|
||||||
installComponents: false,
|
|
||||||
},
|
|
||||||
});*/
|
|
||||||
|
|
||||||
Vue.use(VueMarkdown);
|
Vue.use(VueMarkdown);
|
||||||
Vue.use(Vuetify);
|
Vue.use(Vuetify);
|
||||||
Vue.use(Vuex);
|
|
||||||
let language = window.navigator.userLanguage || window.navigator.language;
|
let language = window.navigator.userLanguage || window.navigator.language;
|
||||||
moment.locale(language);
|
moment.locale(language);
|
||||||
|
|
||||||
|
@ -43,8 +28,6 @@ if (!(language in translations)) {
|
||||||
[language] = language.split('-', 1);
|
[language] = language.split('-', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = new Vuex.Store(storeData);
|
|
||||||
|
|
||||||
Vue.use(VuexI18n.plugin, store);
|
Vue.use(VuexI18n.plugin, store);
|
||||||
|
|
||||||
Object.entries(translations).forEach((key) => {
|
Object.entries(translations).forEach((key) => {
|
||||||
|
@ -55,17 +38,21 @@ Vue.i18n.set(language);
|
||||||
Vue.i18n.fallback('en');
|
Vue.i18n.fallback('en');
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
if (to.matched.some(record => record.meta.requiredAuth) && store.state.user === undefined || store.state.user == null) {
|
if (to.matched.some(record => record.meta.requiredAuth) && !store.state.user) {
|
||||||
next({
|
next({
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
query: { redirect: to.fullPath }
|
query: { redirect: to.fullPath },
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
auth.getUser(store, () => {}, () => {});
|
auth.getUser(store, () => {}, (error) => {
|
||||||
|
console.warn(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('store', store);
|
||||||
|
|
||||||
/* eslint-disable no-new */
|
/* eslint-disable no-new */
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|
|
@ -18,6 +18,7 @@ import Account from '@/components/Account/Account';
|
||||||
import CreateGroup from '@/components/Group/Create';
|
import CreateGroup from '@/components/Group/Create';
|
||||||
import Group from '@/components/Group/Group';
|
import Group from '@/components/Group/Group';
|
||||||
import GroupList from '@/components/Group/GroupList';
|
import GroupList from '@/components/Group/GroupList';
|
||||||
|
import Identities from '../components/Account/Identities.vue';
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
|
@ -110,6 +111,12 @@ const router = new Router({
|
||||||
props: true,
|
props: true,
|
||||||
meta: { requiredAuth: false },
|
meta: { requiredAuth: false },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/identities',
|
||||||
|
name: 'Identities',
|
||||||
|
component: Identities,
|
||||||
|
meta: { requiredAuth: true },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/groups',
|
path: '/groups',
|
||||||
name: 'GroupList',
|
name: 'GroupList',
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import { LOGIN_USER, LOGOUT_USER, LOAD_USER } from './mutation-types';
|
import Vue from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
import { LOGIN_USER, LOGOUT_USER, LOAD_USER, CHANGE_ACTOR } from './mutation-types';
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
isLogged: !!localStorage.getItem('token'),
|
isLogged: !!localStorage.getItem('token'),
|
||||||
user: false,
|
user: false,
|
||||||
|
actor: false,
|
||||||
|
defaultActor: localStorage.getItem('defaultActor') || null,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
@ -20,7 +24,21 @@ const mutations = {
|
||||||
state.isLogged = false;
|
state.isLogged = false;
|
||||||
state.user = null;
|
state.user = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[CHANGE_ACTOR](state, actor) {
|
||||||
|
state.actor = actor;
|
||||||
|
state.defaultActor = actor.username;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
export default { state, mutations };
|
Vue.use(Vuex);
|
||||||
|
const store = new Vuex.Store({ state, mutations });
|
||||||
|
|
||||||
|
store.subscribe((mutation, localState) => {
|
||||||
|
if (mutation === CHANGE_ACTOR) {
|
||||||
|
localStorage.setItem('defaultActor', localState.actor.username);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default store;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
export const LOGIN_USER = 'LOGIN_USER';
|
export const LOGIN_USER = 'LOGIN_USER';
|
||||||
export const LOAD_USER = 'LOAD_USER';
|
export const LOAD_USER = 'LOAD_USER';
|
||||||
export const LOGOUT_USER = 'LOGOUT_USER';
|
export const LOGOUT_USER = 'LOGOUT_USER';
|
||||||
|
export const CHANGE_ACTOR = 'CHANGE_ACTOR';
|
||||||
|
|
|
@ -68,7 +68,7 @@ defmodule Eventos.Actors.Actor do
|
||||||
many_to_many :followers, Actor, join_through: Follower
|
many_to_many :followers, Actor, join_through: Follower
|
||||||
has_many :organized_events, Event, [foreign_key: :organizer_actor_id]
|
has_many :organized_events, Event, [foreign_key: :organizer_actor_id]
|
||||||
many_to_many :memberships, Actor, join_through: Member
|
many_to_many :memberships, Actor, join_through: Member
|
||||||
has_one :user, User
|
belongs_to :user, User
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
@ -76,14 +76,15 @@ defmodule Eventos.Actors.Actor do
|
||||||
@doc false
|
@doc false
|
||||||
def changeset(%Actor{} = actor, attrs) do
|
def changeset(%Actor{} = actor, attrs) do
|
||||||
actor
|
actor
|
||||||
|> Ecto.Changeset.cast(attrs, [:url, :outbox_url, :inbox_url, :shared_inbox_url, :following_url, :followers_url, :type, :name, :domain, :summary, :preferred_username, :keys, :manually_approves_followers, :suspended, :avatar_url, :banner_url])
|
|> Ecto.Changeset.cast(attrs, [:url, :outbox_url, :inbox_url, :shared_inbox_url, :following_url, :followers_url, :type, :name, :domain, :summary, :preferred_username, :keys, :manually_approves_followers, :suspended, :avatar_url, :banner_url, :user_id])
|
||||||
|
|> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{attrs["prefered_username"]}")
|
||||||
|> validate_required([:preferred_username, :keys, :suspended, :url])
|
|> validate_required([:preferred_username, :keys, :suspended, :url])
|
||||||
|> unique_constraint(:prefered_username, name: :actors_preferred_username_domain_index)
|
|> unique_constraint(:prefered_username, name: :actors_preferred_username_domain_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_changeset(%Actor{} = actor, attrs) do
|
def registration_changeset(%Actor{} = actor, attrs) do
|
||||||
actor
|
actor
|
||||||
|> Ecto.Changeset.cast(attrs, [:preferred_username, :domain, :name, :summary, :keys, :keys, :suspended, :url, :type, :avatar_url])
|
|> Ecto.Changeset.cast(attrs, [:preferred_username, :domain, :name, :summary, :keys, :keys, :suspended, :url, :type, :avatar_url, :user_id])
|
||||||
|> unique_constraint(:preferred_username, name: :actors_preferred_username_domain_index)
|
|> unique_constraint(:preferred_username, name: :actors_preferred_username_domain_index)
|
||||||
|> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{attrs["prefered_username"]}")
|
|> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{attrs["prefered_username"]}")
|
||||||
|> validate_required([:preferred_username, :keys, :suspended, :url, :type])
|
|> validate_required([:preferred_username, :keys, :suspended, :url, :type])
|
||||||
|
|
|
@ -177,7 +177,7 @@ defmodule Eventos.Actors do
|
||||||
|
|
||||||
def list_users_with_actors do
|
def list_users_with_actors do
|
||||||
users = Repo.all(User)
|
users = Repo.all(User)
|
||||||
Repo.preload(users, :actor)
|
Repo.preload(users, :actors)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp blank?(""), do: nil
|
defp blank?(""), do: nil
|
||||||
|
@ -222,7 +222,7 @@ defmodule Eventos.Actors do
|
||||||
|
|
||||||
def get_user_with_actor!(id) do
|
def get_user_with_actor!(id) do
|
||||||
user = Repo.get!(User, id)
|
user = Repo.get!(User, id)
|
||||||
Repo.preload(user, :actor)
|
Repo.preload(user, :actors)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_actor_by_url(url) do
|
def get_actor_by_url(url) do
|
||||||
|
@ -312,7 +312,7 @@ defmodule Eventos.Actors do
|
||||||
Get an user by email
|
Get an user by email
|
||||||
"""
|
"""
|
||||||
def find_by_email(email) do
|
def find_by_email(email) do
|
||||||
case Repo.preload(Repo.get_by(User, email: email), :actor) do
|
case Repo.preload(Repo.get_by(User, email: email), :actors) do
|
||||||
nil ->
|
nil ->
|
||||||
{:error, nil}
|
{:error, nil}
|
||||||
user ->
|
user ->
|
||||||
|
|
|
@ -8,8 +8,9 @@ defmodule Eventos.Actors.Service.Activation do
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def check_confirmation_token(token) when is_binary(token) do
|
def check_confirmation_token(token) when is_binary(token) do
|
||||||
with %User{} = user <- Repo.get_by(User, confirmation_token: token) do
|
with %User{} = user <- Repo.get_by(User, confirmation_token: token),
|
||||||
Actors.update_user(user, %{"confirmed_at" => DateTime.utc_now(), "confirmation_sent_at" => nil, "confirmation_token" => nil})
|
{:ok, %User{} = user} <- Actors.update_user(user, %{"confirmed_at" => DateTime.utc_now(), "confirmation_sent_at" => nil, "confirmation_token" => nil}) do
|
||||||
|
{:ok, Repo.preload(user, :actors)}
|
||||||
else
|
else
|
||||||
_err ->
|
_err ->
|
||||||
{:error, "Invalid token"}
|
{:error, "Invalid token"}
|
||||||
|
|
|
@ -11,7 +11,7 @@ defmodule Eventos.Actors.User do
|
||||||
field :password_hash, :string
|
field :password_hash, :string
|
||||||
field :password, :string, virtual: true
|
field :password, :string, virtual: true
|
||||||
field :role, :integer, default: 0
|
field :role, :integer, default: 0
|
||||||
belongs_to :actor, Actor
|
has_many :actors, Actor
|
||||||
field :confirmed_at, :utc_datetime
|
field :confirmed_at, :utc_datetime
|
||||||
field :confirmation_sent_at, :utc_datetime
|
field :confirmation_sent_at, :utc_datetime
|
||||||
field :confirmation_token, :string
|
field :confirmation_token, :string
|
||||||
|
@ -24,7 +24,7 @@ defmodule Eventos.Actors.User do
|
||||||
@doc false
|
@doc false
|
||||||
def changeset(%User{} = user, attrs) do
|
def changeset(%User{} = user, attrs) do
|
||||||
user
|
user
|
||||||
|> cast(attrs, [:email, :role, :password_hash, :actor_id, :confirmed_at, :confirmation_sent_at, :confirmation_token, :reset_password_sent_at, :reset_password_token])
|
|> cast(attrs, [:email, :role, :password_hash, :confirmed_at, :confirmation_sent_at, :confirmation_token, :reset_password_sent_at, :reset_password_token])
|
||||||
|> validate_required([:email])
|
|> validate_required([:email])
|
||||||
|> unique_constraint(:email, [message: "registration.error.email_already_used"])
|
|> unique_constraint(:email, [message: "registration.error.email_already_used"])
|
||||||
|> validate_format(:email, ~r/@/)
|
|> validate_format(:email, ~r/@/)
|
||||||
|
|
|
@ -5,7 +5,7 @@ defmodule EventosWeb.ActorController do
|
||||||
use EventosWeb, :controller
|
use EventosWeb, :controller
|
||||||
|
|
||||||
alias Eventos.Actors
|
alias Eventos.Actors
|
||||||
alias Eventos.Actors.Actor
|
alias Eventos.Actors.{Actor, User}
|
||||||
alias Eventos.Service.ActivityPub
|
alias Eventos.Service.ActivityPub
|
||||||
|
|
||||||
action_fallback EventosWeb.FallbackController
|
action_fallback EventosWeb.FallbackController
|
||||||
|
@ -15,6 +15,26 @@ defmodule EventosWeb.ActorController do
|
||||||
render(conn, "index.json", actors: actors)
|
render(conn, "index.json", actors: actors)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create(conn, %{"actor" => actor_params}) do
|
||||||
|
with %User{} = user <- Guardian.Plug.current_resource(conn),
|
||||||
|
actor_params <- Map.put(actor_params, "user_id", user.id),
|
||||||
|
actor_params <- Map.put(actor_params, "keys", keys_for_account()),
|
||||||
|
{:ok, %Actor{} = actor} <- Actors.create_actor(actor_params) do
|
||||||
|
conn
|
||||||
|
|> put_status(:created)
|
||||||
|
|> put_resp_header("location", actor_path(conn, :show, actor.preferred_username))
|
||||||
|
|> render("show_basic.json", actor: actor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp keys_for_account() do
|
||||||
|
key = :public_key.generate_key({:rsa, 2048, 65_537})
|
||||||
|
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
|
||||||
|
[entry]
|
||||||
|
|> :public_key.pem_encode()
|
||||||
|
|> String.trim_trailing()
|
||||||
|
end
|
||||||
|
|
||||||
def show(conn, %{"name" => name}) do
|
def show(conn, %{"name" => name}) do
|
||||||
actor = Actors.get_actor_by_name_with_everything(name)
|
actor = Actors.get_actor_by_name_with_everything(name)
|
||||||
render(conn, "show.json", actor: actor)
|
render(conn, "show.json", actor: actor)
|
||||||
|
|
|
@ -20,7 +20,7 @@ defmodule EventosWeb.GroupController do
|
||||||
conn
|
conn
|
||||||
|> put_status(:created)
|
|> put_status(:created)
|
||||||
|> put_resp_header("location", actor_path(conn, :show, group))
|
|> put_resp_header("location", actor_path(conn, :show, group))
|
||||||
|> render(EventosWeb.ActorView, "acccount_basic.json", actor: group)
|
|> render(EventosWeb.ActorView, "actor_basic.json", actor: group)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ defmodule EventosWeb.UserController do
|
||||||
def show_current_actor(conn, _params) do
|
def show_current_actor(conn, _params) do
|
||||||
user = conn
|
user = conn
|
||||||
|> Guardian.Plug.current_resource()
|
|> Guardian.Plug.current_resource()
|
||||||
|> Repo.preload(:actor)
|
|> Repo.preload(:actors)
|
||||||
render(conn, "show_simple.json", user: user)
|
render(conn, "show_simple.json", user: user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ defmodule EventosWeb.Router do
|
||||||
get "/user", UserController, :show_current_actor
|
get "/user", UserController, :show_current_actor
|
||||||
post "/sign-out", UserSessionController, :sign_out
|
post "/sign-out", UserSessionController, :sign_out
|
||||||
resources "/users", UserController, except: [:new, :edit, :show]
|
resources "/users", UserController, except: [:new, :edit, :show]
|
||||||
|
post "/actors", ActorController, :create
|
||||||
patch "/actors/:name", ActorController, :update
|
patch "/actors/:name", ActorController, :update
|
||||||
post "/events", EventController, :create
|
post "/events", EventController, :create
|
||||||
patch "/events/:uuid", EventController, :update
|
patch "/events/:uuid", EventController, :update
|
||||||
|
|
|
@ -7,7 +7,7 @@ defmodule EventosWeb.ActorView do
|
||||||
alias Eventos.Actors
|
alias Eventos.Actors
|
||||||
|
|
||||||
def render("index.json", %{actors: actors}) do
|
def render("index.json", %{actors: actors}) do
|
||||||
%{data: render_many(actors, ActorView, "acccount_basic.json")}
|
%{data: render_many(actors, ActorView, "actor_basic.json")}
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("show.json", %{actor: actor}) do
|
def render("show.json", %{actor: actor}) do
|
||||||
|
@ -18,7 +18,7 @@ defmodule EventosWeb.ActorView do
|
||||||
%{data: render_one(actor, ActorView, "actor_basic.json")}
|
%{data: render_one(actor, ActorView, "actor_basic.json")}
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("acccount_basic.json", %{actor: actor}) do
|
def render("actor_basic.json", %{actor: actor}) do
|
||||||
%{id: actor.id,
|
%{id: actor.id,
|
||||||
username: actor.preferred_username,
|
username: actor.preferred_username,
|
||||||
domain: actor.domain,
|
domain: actor.domain,
|
||||||
|
|
|
@ -53,8 +53,8 @@ defmodule EventosWeb.EventView do
|
||||||
begins_on: event.begins_on,
|
begins_on: event.begins_on,
|
||||||
ends_on: event.ends_on,
|
ends_on: event.ends_on,
|
||||||
uuid: event.uuid,
|
uuid: event.uuid,
|
||||||
organizer: render_one(event.organizer_actor, ActorView, "acccount_basic.json"),
|
organizer: render_one(event.organizer_actor, ActorView, "actor_basic.json"),
|
||||||
participants: render_many(event.participants, ActorView, "acccount_basic.json"),
|
participants: render_many(event.participants, ActorView, "actor_basic.json"),
|
||||||
physical_address: render_one(event.physical_address, AddressView, "address.json"),
|
physical_address: render_one(event.physical_address, AddressView, "address.json"),
|
||||||
type: "Event",
|
type: "Event",
|
||||||
address_type: event.address_type,
|
address_type: event.address_type,
|
||||||
|
|
|
@ -32,7 +32,7 @@ defmodule EventosWeb.GroupView do
|
||||||
description: group.description,
|
description: group.description,
|
||||||
suspended: group.suspended,
|
suspended: group.suspended,
|
||||||
url: group.url,
|
url: group.url,
|
||||||
members: render_many(group.members, ActorView, "acccount_basic.json"),
|
members: render_many(group.members, ActorView, "actor_basic.json"),
|
||||||
events: render_many(group.organized_events, EventView, "event_simple.json")
|
events: render_many(group.organized_events, EventView, "event_simple.json")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule EventosWeb.MemberView do
|
||||||
def render("member.json", %{member: member}) do
|
def render("member.json", %{member: member}) do
|
||||||
%{
|
%{
|
||||||
role: member.role,
|
role: member.role,
|
||||||
actor: render_one(member.actor, ActorView, "acccount_basic.json"),
|
actor: render_one(member.actor, ActorView, "actor_basic.json"),
|
||||||
group: render_one(member.parent, ActorView, "acccount_basic.json")
|
group: render_one(member.parent, ActorView, "actor_basic.json")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ defmodule EventosWeb.SearchView do
|
||||||
%{
|
%{
|
||||||
data: %{
|
data: %{
|
||||||
events: render_many(events, EventView, "event_simple.json"),
|
events: render_many(events, EventView, "event_simple.json"),
|
||||||
actors: render_many(actors, ActorView, "acccount_basic.json"),
|
actors: render_many(actors, ActorView, "actor_basic.json"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,14 +28,14 @@ defmodule EventosWeb.UserView do
|
||||||
def render("user_simple.json", %{user: user}) do
|
def render("user_simple.json", %{user: user}) do
|
||||||
%{id: user.id,
|
%{id: user.id,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
actor: render_one(user.actor, ActorView, "acccount_basic.json")
|
actors: render_many(user.actors, ActorView, "actor_basic.json")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("user.json", %{user: user}) do
|
def render("user.json", %{user: user}) do
|
||||||
%{id: user.id,
|
%{id: user.id,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
actor: render_one(user.actor, ActorView, "actor.json")
|
actors: render_many(user.actors, ActorView, "actor.json")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
19
mix.exs
19
mix.exs
|
@ -6,13 +6,18 @@ defmodule Eventos.Mixfile do
|
||||||
app: :eventos,
|
app: :eventos,
|
||||||
version: "0.0.1",
|
version: "0.0.1",
|
||||||
elixir: "~> 1.4",
|
elixir: "~> 1.4",
|
||||||
elixirc_paths: elixirc_paths(Mix.env),
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
compilers: [:phoenix, :gettext] ++ Mix.compilers,
|
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
|
||||||
start_permanent: Mix.env == :prod,
|
start_permanent: Mix.env() == :prod,
|
||||||
aliases: aliases(),
|
aliases: aliases(),
|
||||||
deps: deps(),
|
deps: deps(),
|
||||||
test_coverage: [tool: ExCoveralls],
|
test_coverage: [tool: ExCoveralls],
|
||||||
preferred_cli_env: ["coveralls": :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test],
|
preferred_cli_env: [
|
||||||
|
coveralls: :test,
|
||||||
|
"coveralls.detail": :test,
|
||||||
|
"coveralls.post": :test,
|
||||||
|
"coveralls.html": :test
|
||||||
|
],
|
||||||
name: "Eventos",
|
name: "Eventos",
|
||||||
source_url: "https://framagit.org/tcit/eventos",
|
source_url: "https://framagit.org/tcit/eventos",
|
||||||
homepage_url: "https://framagit.org/tcit/eventos",
|
homepage_url: "https://framagit.org/tcit/eventos",
|
||||||
|
@ -32,7 +37,7 @@ defmodule Eventos.Mixfile do
|
||||||
|
|
||||||
# Specifies which paths to compile per environment.
|
# Specifies which paths to compile per environment.
|
||||||
defp elixirc_paths(:test), do: ["lib", "test/support"]
|
defp elixirc_paths(:test), do: ["lib", "test/support"]
|
||||||
defp elixirc_paths(_), do: ["lib"]
|
defp elixirc_paths(_), do: ["lib"]
|
||||||
|
|
||||||
# Specifies your project dependencies.
|
# Specifies your project dependencies.
|
||||||
#
|
#
|
||||||
|
@ -72,7 +77,7 @@ defmodule Eventos.Mixfile do
|
||||||
{:geolix, "~> 0.16"},
|
{:geolix, "~> 0.16"},
|
||||||
# Dev and test dependencies
|
# Dev and test dependencies
|
||||||
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
||||||
{:ex_machina, "~> 2.1", only: :test},
|
{:ex_machina, "~> 2.2", only: [:dev, :test]},
|
||||||
{:credo, "~> 0.8", only: [:dev, :test], runtime: false},
|
{:credo, "~> 0.8", only: [:dev, :test], runtime: false},
|
||||||
{:excoveralls, "~> 0.8", only: :test},
|
{:excoveralls, "~> 0.8", only: :test},
|
||||||
{:ex_doc, "~> 0.16", only: :dev, runtime: false},
|
{:ex_doc, "~> 0.16", only: :dev, runtime: false},
|
||||||
|
@ -91,7 +96,7 @@ defmodule Eventos.Mixfile do
|
||||||
[
|
[
|
||||||
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
|
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
|
||||||
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
||||||
"test": ["ecto.create --quiet", "ecto.migrate", "test"]
|
test: ["ecto.create --quiet", "ecto.migrate", "test"]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,15 +2,18 @@ defmodule Eventos.Repo.Migrations.Prerequites do
|
||||||
use Ecto.Migration
|
use Ecto.Migration
|
||||||
|
|
||||||
def up do
|
def up do
|
||||||
execute """
|
execute("""
|
||||||
CREATE TYPE datetimetz AS (
|
CREATE TYPE datetimetz AS (
|
||||||
dt timestamptz,
|
dt timestamptz,
|
||||||
tz varchar
|
tz varchar
|
||||||
);
|
);
|
||||||
"""
|
""")
|
||||||
|
|
||||||
|
execute("CREATE EXTENSION IF NOT EXISTS postgis")
|
||||||
end
|
end
|
||||||
|
|
||||||
def down do
|
def down do
|
||||||
execute "DROP TYPE IF EXISTS datetimetz;"
|
execute("DROP TYPE IF EXISTS datetimetz;")
|
||||||
|
execute("DROP EXTENSION IF EXISTS postgis")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
defmodule Eventos.Repo.Migrations.AllowMultipleAccountsForUser do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
alter table(:actors) do
|
||||||
|
add :user_id, references(:users, on_delete: :delete_all), null: true
|
||||||
|
end
|
||||||
|
|
||||||
|
alter table(:users) do
|
||||||
|
remove :actor_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
alter table(:users) do
|
||||||
|
add :actor_id, references(:actors, on_delete: :delete_all), null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
alter table(:actors) do
|
||||||
|
remove :user_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,2 +0,0 @@
|
||||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var u,i,f,s=0,l=[];s<t.length;s++)i=t[s],o[i]&&l.push(o[i][0]),o[i]=0;for(u in c)Object.prototype.hasOwnProperty.call(c,u)&&(e[u]=c[u]);for(r&&r(t,c,a);l.length;)l.shift()();if(a)for(s=0;s<a.length;s++)f=n(n.s=a[s]);return f};var t={},o={2:0};n.e=function(e){function r(){u.onerror=u.onload=null,clearTimeout(i);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var a=document.getElementsByTagName("head")[0],u=document.createElement("script");u.type="text/javascript",u.charset="utf-8",u.async=!0,u.timeout=12e4,n.nc&&u.setAttribute("nonce",n.nc),u.src=n.p+"js/"+e+"."+{0:"0d63a19c6680451dd336",1:"29c4f33994925affb616"}[e]+".js";var i=setTimeout(r,12e4);return u.onerror=u.onload=r,a.appendChild(u),c},n.m=e,n.c=t,n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="/",n.oe=function(e){throw console.error(e),e}}([]);
|
|
||||||
//# sourceMappingURL=manifest.881ff1dba0c9e5d0130f.js.map
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -37,7 +37,6 @@ defmodule Eventos.ActorsTest do
|
||||||
assert actor.domain == "some domain"
|
assert actor.domain == "some domain"
|
||||||
assert actor.keys == "some keypair"
|
assert actor.keys == "some keypair"
|
||||||
assert actor.suspended
|
assert actor.suspended
|
||||||
assert actor.url == "some url"
|
|
||||||
assert actor.preferred_username == "some username"
|
assert actor.preferred_username == "some username"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,7 +53,6 @@ defmodule Eventos.ActorsTest do
|
||||||
assert actor.domain == "some updated domain"
|
assert actor.domain == "some updated domain"
|
||||||
assert actor.keys == "some updated keys"
|
assert actor.keys == "some updated keys"
|
||||||
refute actor.suspended
|
refute actor.suspended
|
||||||
assert actor.url == "some updated url"
|
|
||||||
assert actor.preferred_username == "some updated username"
|
assert actor.preferred_username == "some updated username"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,29 @@ defmodule EventosWeb.ActorControllerTest do
|
||||||
alias Eventos.Actors
|
alias Eventos.Actors
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: conn, user: user}
|
{:ok, conn: conn, user: user, actor: actor}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
key = :public_key.generate_key({:rsa, 2048, 65_537})
|
||||||
|
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
|
||||||
|
pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing()
|
||||||
|
|
||||||
|
@create_attrs %{preferred_username: "otheridentity", summary: "This is my other identity", domain: nil, keys: pem, user: nil}
|
||||||
|
|
||||||
describe "index" do
|
describe "index" do
|
||||||
test "lists all actors", %{conn: conn, user: user} do
|
test "lists all actors", %{conn: conn, user: user, actor: actor} do
|
||||||
conn = get conn, actor_path(conn, :index)
|
conn = get conn, actor_path(conn, :index)
|
||||||
assert hd(json_response(conn, 200)["data"])["username"] == user.actor.preferred_username
|
assert hd(json_response(conn, 200)["data"])["username"] == actor.preferred_username
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "create actor" do
|
||||||
|
test "from an existing user", %{conn: conn, user: user} do
|
||||||
|
conn = auth_conn(conn, user)
|
||||||
|
conn = post conn, actor_path(conn, :create), actor: @create_attrs
|
||||||
|
assert json_response(conn, 201)["data"]["username"] == @create_attrs.preferred_username
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,9 +55,4 @@ defmodule EventosWeb.ActorControllerTest do
|
||||||
# assert response(conn, 200)
|
# assert response(conn, 200)
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
defp create_actor(_) do
|
|
||||||
actor = insert(:actor)
|
|
||||||
{:ok, actor: actor}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule EventosWeb.AddressControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: conn, user: user}
|
{:ok, conn: conn, user: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ defmodule EventosWeb.BotControllerTest do
|
||||||
@invalid_attrs %{source: nil, type: nil, name: nil}
|
@invalid_attrs %{source: nil, type: nil, name: nil}
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: put_req_header(conn, "accept", "application/json"), user: user}
|
{:ok, conn: put_req_header(conn, "accept", "application/json"), user: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule EventosWeb.CategoryControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: conn, user: user}
|
{:ok, conn: conn, user: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,14 @@ defmodule EventosWeb.CommentControllerTest do
|
||||||
@invalid_attrs %{text: nil, url: nil}
|
@invalid_attrs %{text: nil, url: nil}
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: put_req_header(conn, "accept", "application/json"), user: user}
|
{:ok, conn: put_req_header(conn, "accept", "application/json"), user: user, actor: actor}
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "create comment" do
|
describe "create comment" do
|
||||||
test "renders comment when data is valid", %{conn: conn, user: user} do
|
test "renders comment when data is valid", %{conn: conn, user: user, actor: actor} do
|
||||||
conn = auth_conn(conn, user)
|
conn = auth_conn(conn, user)
|
||||||
actor = insert(:actor)
|
|
||||||
attrs = Map.merge(@create_attrs, %{actor_id: actor.id})
|
attrs = Map.merge(@create_attrs, %{actor_id: actor.id})
|
||||||
conn = post conn, comment_path(conn, :create), comment: attrs
|
conn = post conn, comment_path(conn, :create), comment: attrs
|
||||||
assert %{"uuid" => uuid, "id" => id} = json_response(conn, 201)["data"]
|
assert %{"uuid" => uuid, "id" => id} = json_response(conn, 201)["data"]
|
||||||
|
@ -43,9 +42,8 @@ defmodule EventosWeb.CommentControllerTest do
|
||||||
describe "update comment" do
|
describe "update comment" do
|
||||||
setup [:create_comment]
|
setup [:create_comment]
|
||||||
|
|
||||||
test "renders comment when data is valid", %{conn: conn, comment: %Comment{id: id, uuid: uuid} = comment, user: user} do
|
test "renders comment when data is valid", %{conn: conn, comment: %Comment{id: id, uuid: uuid} = comment, user: user, actor: actor} do
|
||||||
conn = auth_conn(conn, user)
|
conn = auth_conn(conn, user)
|
||||||
actor = insert(:actor)
|
|
||||||
attrs = Map.merge(@update_attrs, %{actor_id: actor.id})
|
attrs = Map.merge(@update_attrs, %{actor_id: actor.id})
|
||||||
conn = put conn, comment_path(conn, :update, uuid), comment: attrs
|
conn = put conn, comment_path(conn, :update, uuid), comment: attrs
|
||||||
assert %{"uuid" => uuid, "id" => id} = json_response(conn, 200)["data"]
|
assert %{"uuid" => uuid, "id" => id} = json_response(conn, 200)["data"]
|
||||||
|
|
|
@ -21,9 +21,9 @@ defmodule EventosWeb.EventControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: conn, user: user}
|
{:ok, conn: conn, user: user, actor: actor}
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "index" do
|
describe "index" do
|
||||||
|
@ -34,8 +34,8 @@ defmodule EventosWeb.EventControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "create event" do
|
describe "create event" do
|
||||||
test "renders event when data is valid", %{conn: conn, user: user} do
|
test "renders event when data is valid", %{conn: conn, user: user, actor: actor} do
|
||||||
attrs = Map.put(@create_attrs, :organizer_actor_id, user.actor.id)
|
attrs = Map.put(@create_attrs, :organizer_actor_id, actor.id)
|
||||||
attrs = Map.put(attrs, "physical_address", @create_address_attrs)
|
attrs = Map.put(attrs, "physical_address", @create_address_attrs)
|
||||||
|
|
||||||
category = insert(:category)
|
category = insert(:category)
|
||||||
|
@ -55,9 +55,9 @@ defmodule EventosWeb.EventControllerTest do
|
||||||
} = json_response(conn, 200)["data"]
|
} = json_response(conn, 200)["data"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "renders errors when data is invalid", %{conn: conn, user: user} do
|
test "renders errors when data is invalid", %{conn: conn, user: user, actor: actor} do
|
||||||
conn = auth_conn(conn, user)
|
conn = auth_conn(conn, user)
|
||||||
attrs = Map.put(@invalid_attrs, :organizer_actor_id, user.actor.id)
|
attrs = Map.put(@invalid_attrs, :organizer_actor_id, actor.id)
|
||||||
attrs = Map.put(attrs, :address, @create_address_attrs)
|
attrs = Map.put(attrs, :address, @create_address_attrs)
|
||||||
conn = post conn, event_path(conn, :create), event: attrs
|
conn = post conn, event_path(conn, :create), event: attrs
|
||||||
assert json_response(conn, 422)["errors"] != %{}
|
assert json_response(conn, 422)["errors"] != %{}
|
||||||
|
@ -78,10 +78,10 @@ defmodule EventosWeb.EventControllerTest do
|
||||||
describe "update event" do
|
describe "update event" do
|
||||||
setup [:create_event]
|
setup [:create_event]
|
||||||
|
|
||||||
test "renders event when data is valid", %{conn: conn, event: %Event{uuid: uuid} = event, user: user} do
|
test "renders event when data is valid", %{conn: conn, event: %Event{uuid: uuid} = event, user: user, actor: actor} do
|
||||||
conn = auth_conn(conn, user)
|
conn = auth_conn(conn, user)
|
||||||
address = address_fixture()
|
address = address_fixture()
|
||||||
attrs = Map.put(@update_attrs, :organizer_actor_id, user.actor.id)
|
attrs = Map.put(@update_attrs, :organizer_actor_id, actor.id)
|
||||||
attrs = Map.put(attrs, :address_id, address.id)
|
attrs = Map.put(attrs, :address_id, address.id)
|
||||||
conn = put conn, event_path(conn, :update, uuid), event: attrs
|
conn = put conn, event_path(conn, :update, uuid), event: attrs
|
||||||
assert %{"uuid" => uuid} = json_response(conn, 200)["data"]
|
assert %{"uuid" => uuid} = json_response(conn, 200)["data"]
|
||||||
|
@ -97,9 +97,9 @@ defmodule EventosWeb.EventControllerTest do
|
||||||
} = json_response(conn, 200)["data"]
|
} = json_response(conn, 200)["data"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "renders errors when data is invalid", %{conn: conn, event: %Event{uuid: uuid} = event, user: user} do
|
test "renders errors when data is invalid", %{conn: conn, event: %Event{uuid: uuid} = event, user: user, actor: actor} do
|
||||||
conn = auth_conn(conn, user)
|
conn = auth_conn(conn, user)
|
||||||
attrs = Map.put(@invalid_attrs, :organizer_actor_id, user.actor.id)
|
attrs = Map.put(@invalid_attrs, :organizer_actor_id, actor.id)
|
||||||
conn = put conn, event_path(conn, :update, uuid), event: attrs
|
conn = put conn, event_path(conn, :update, uuid), event: attrs
|
||||||
assert json_response(conn, 422)["errors"] != %{}
|
assert json_response(conn, 422)["errors"] != %{}
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule EventosWeb.SessionControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
event = insert(:event, organizer_actor: actor)
|
event = insert(:event, organizer_actor: actor)
|
||||||
{:ok, conn: conn, user: user, event: event}
|
{:ok, conn: conn, user: user, event: event}
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule EventosWeb.TagControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: conn, user: user}
|
{:ok, conn: conn, user: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule EventosWeb.TrackControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
event = insert(:event, organizer_actor: actor)
|
event = insert(:event, organizer_actor: actor)
|
||||||
{:ok, conn: conn, user: user, event: event}
|
{:ok, conn: conn, user: user, event: event}
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule EventosWeb.UserControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
actor = insert(:actor)
|
user = insert(:user)
|
||||||
user = insert(:user, actor: actor)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: conn, user: user}
|
{:ok, conn: conn, user: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ defmodule Eventos.Factory do
|
||||||
password_hash: "Jane Smith",
|
password_hash: "Jane Smith",
|
||||||
email: sequence(:email, &"email-#{&1}@example.com"),
|
email: sequence(:email, &"email-#{&1}@example.com"),
|
||||||
role: 0,
|
role: 0,
|
||||||
actor: build(:actor)
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,7 +24,8 @@ defmodule Eventos.Factory do
|
||||||
preferred_username: preferred_username,
|
preferred_username: preferred_username,
|
||||||
domain: nil,
|
domain: nil,
|
||||||
keys: pem,
|
keys: pem,
|
||||||
url: EventosWeb.Endpoint.url() <> "/@#{preferred_username}"
|
url: EventosWeb.Endpoint.url() <> "/@#{preferred_username}",
|
||||||
|
user: nil,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue