Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Story map admin #105

Draft
wants to merge 35 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
76f6d20
Adapt storymap api for admin console
gdozot2 Apr 10, 2024
52b6937
Get data modifications
gdozot2 Apr 15, 2024
115bde7
Standardize stories DB name
gdozot2 Apr 15, 2024
c92a6f4
Log error
gdozot2 Apr 15, 2024
31f7c47
adapt story and chapters
gdozot2 Apr 16, 2024
d42c87b
Update DB + fix order
gdozot2 Apr 24, 2024
ea297ab
Rework story + add tests
gdozot2 May 8, 2024
26ccb9d
update tests
gdozot2 May 8, 2024
f636914
update tests + update update method
gdozot2 May 14, 2024
aa48e95
Refactor chapter and add tests
gdozot2 May 28, 2024
0275ea6
update db storymap
gdozot2 May 13, 2024
afb47fe
revert code
gdozot2 May 14, 2024
9f41e61
Add type
gdozot2 May 14, 2024
783f709
add news table migration
zweiro Apr 9, 2024
649cb45
wip: add news feature
zweiro Apr 15, 2024
523977f
test: add news /GET tests
zweiro Apr 16, 2024
9eb904c
refactor: add img_alt field to news schema
zweiro Apr 22, 2024
fca3af1
refactor: switch created_at news field to published at
zweiro Apr 26, 2024
177751f
test: update news pagination test values to be hardcoded
zweiro Apr 26, 2024
1cccfe7
Add langFallback ENV variable to show english when local lang does no…
zweiro May 22, 2024
fd14b9c
Get data modifications
gdozot2 Apr 15, 2024
1663646
Standardize stories DB name
gdozot2 Apr 15, 2024
b13c242
Rework story + add tests
gdozot2 May 8, 2024
47e1752
update tests + update update method
gdozot2 May 14, 2024
6aea0e0
Add some tests, fix some issues, add some fixtures
gdozot2 Jun 10, 2024
597c04a
Improve code
gdozot2 Jun 10, 2024
719d95c
fix join sequelize
gdozot2 Jun 10, 2024
0209156
update code to add owner + nbChapters + update all tests and addd mis…
gdozot2 Jun 20, 2024
b820ffb
Story creation and retrieve base on owner management
gdozot2 Jun 24, 2024
d6e748d
Fix tests with user authorization
gdozot2 Jun 24, 2024
128b5b2
Add not authorized user tests
gdozot2 Jun 26, 2024
bc42979
Manage owner right for addition, supression and modification of story…
gdozot2 Jun 26, 2024
6d4a053
improve
gdozot2 Aug 22, 2024
d5f8922
Fix latest test error
gdozot2 Sep 6, 2024
4b8c21b
Merge branch 'main' into story-map-admin
gdozot2 Sep 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.test.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ AUTH_FACEBOOK_APP_ID=foo
AUTH_FACEBOOK_APP_SECRET=foo

TZ=Europe/Zurich

SMAPCOMPUTE_URL=http://localhost:5000/generate
2 changes: 2 additions & 0 deletions app/api/chapters/chapter.openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
post:
summary: Add a chapter to the db.
operationId: addChapter
parameters:
- $ref: "#/components/parameters/LanguageParameter"
requestBody:
required: true
content:
Expand Down
46 changes: 28 additions & 18 deletions app/api/chapters/chapters.controller.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
const { Stories_chapters } = require('../../models');

const models = require("../../models");
const logger = require('../../../config/logger');

//get all the chapters
const getChapters = async (req, res) => {
try {
const chapters = await Stories_chapters.sequelize.query(`
SELECT stories_chapters.title, stories_chapters.type, picture_id,
stories_chapters.url_media, stories_chapters.description, stories_chapters.zoom, stories_chapters.story,
ST_X(images.location) as longitude, ST_Y(images.location) as latitude
FROM stories_chapters, images
WHERE stories_chapters.picture_id = images.id`,
{type: Stories_chapters.sequelize.QueryTypes.SELECT},
)
const basic_attributes = ["picture_id", "title", "type", "url_media", "description", "zoom", "story"];
const longitude = [models.sequelize.literal("ST_X(images.location)"), "longitude"];
const latitude = [models.sequelize.literal("ST_Y(location)"), "latitude"];
gdozot2 marked this conversation as resolved.
Show resolved Hide resolved
const includeOption = [{
model: models.images,
attributes: [longitude, latitude],
}];
const sequelizeQuery = {
attributes: basic_attributes,
orderBy: ["indexinstory"],
include: includeOption
};
const chapters = await models.stories_chapters.findAll(sequelizeQuery);
res.json(chapters);
} catch (error) {
logger.error(error);
res.status(500).json({ error: 'Une erreur s\'est produite lors de la récupération des chapitres.' });
}
};
Expand All @@ -23,69 +29,73 @@ const getChapters = async (req, res) => {
const getChapterById = async (req, res) => {
const { id } = req.params;
try {
const chapter = await Stories_chapters.findByPk(id);
const chapter = await models.stories_chapters.findByPk(id);
if (chapter) {
res.json(JSON.stringify({ "chapters": chapter }));
} else {
res.status(404).json({ error: 'Aucun chapitre trouvé avec cet ID.' });
}
} catch (error) {
logger.error(error);
res.status(500).json({ error: `Une erreur s'est produite lors de la récupération du chapitre avec l'ID ${id}.` });
}
};


//Add a chapter to the db
const addChapter = async (req, res) => {
const { title, type, picture_id, url_media, description, zoom, story, indexInStory } = req.body;
const { title, type, picture_id, url_media, description, zoom, story, indexinstory } = req.body;
try {
const newChapter = await Stories_chapters.create({
const newChapter = await models.stories_chapters.create({
title,
type,
picture_id,
url_media,
description,
zoom,
story,
indexInStory
indexinstory
});
res.status(201).json(newChapter); // Return the ID of the newly created chapter
} catch (error) {
logger.error(error);
res.status(500).json({ error: 'Une erreur s\'est produite lors de l\'ajout du chapitre.' });
}
};


//Update a chapter
const updateChapter = async (req, res) => {
const { title, type, picture_id, url_media, description, zoom, story, indexInStory } = req.body;
const { title, type, picture_id, url_media, description, zoom, story, indexinstory } = req.body;
try {
const updatedChapter = await Stories_chapters.update({
const updatedChapter = await models.stories_chapters.update({
title,
type,
picture_id,
url_media,
description,
zoom,
story,
indexInStory
indexinstory
},{

where: {id: req.params.id},
});
res.status(201).json(updatedChapter); // Return the ID of the newly created chapter
} catch (error) {
logger.error(error);
res.status(500).json({ error: 'Une erreur s\'est produite lors de la misz à jour du chapitre.' });
}
};

const deleteChapter = async (req, res) =>{

try{
const deletedChapter = await Stories_chapters.destroy({where: {id:req.params.id}});
const deletedChapter = await models.stories_chapters.destroy({where: {id:req.params.id}});
res.status(200).json(deletedChapter);

}catch(error){
logger.error(error);
res.status(500).json({error: "Une erreur c'est produite lors de la supression du chapitre"});
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/api/chapters/schemas/chapters.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"story":{
"type": "integer"
},
"indexInStory":{
"indexinstory":{
"type": "integer"
}

Expand Down
12 changes: 3 additions & 9 deletions app/api/stories/schemas/stories.list.schema.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
{
"$id": "StoriesList",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {

"rows": {
"type": "array",
"items": {
"$ref": "Stories#"
}
}
"type": "array",
"items": {
"$ref": "Stories#"
},
"additionalProperties": false
}
10 changes: 9 additions & 1 deletion app/api/stories/schemas/stories.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {

"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"logo_link": {
"type": "string"
},
"description": {
"type": "string"
},
"description_preview": {
"type": "string"
}

},
Expand Down
61 changes: 35 additions & 26 deletions app/api/stories/stories.controller.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
const { Stories, Stories_chapters } = require("../../models");
const models = require("../../models");
const logger = require('../../../config/logger');

//get all the stories
const getStories = async (req, res) => {
try {
const stories = await Stories.findAll();
const stories = await models.stories.findAll();
res.json(stories);
} catch (error) {
logger.error(error);
res.status(500).json({ error: 'Une erreur s\'est produite lors de la récupération des stories.' });
}
};
Expand All @@ -15,30 +17,31 @@ const getStories = async (req, res) => {
const getStoryById = async (req, res) => {
const { id } = req.params;
try {
const story = await Stories.findByPk(id);
const chaptersOfStory = await Stories_chapters.sequelize.query(`
SELECT stories_chapters.title, stories_chapters.type, picture_id,
stories_chapters.url_media, stories_chapters.description, stories_chapters.zoom, stories_chapters.story,
ST_X(images.location) as longitude, ST_Y(images.location) as latitude
FROM stories_chapters, images
WHERE stories_chapters.picture_id = images.id
AND stories_chapters.story = :storyId
ORDER BY stories_chapters.indexinstory`,
{
replacements: { storyId: id },
type: Stories_chapters.sequelize.QueryTypes.SELECT},
)
story.dataValues.chapters = chaptersOfStory;



const story = await models.stories.findByPk(id);

const basic_attributes = ["id", "picture_id", "title", "type", "url_media", "description", "zoom", "story", "indexinstory"];
const longitude = [models.sequelize.literal("ST_X(images.location)"), "longitude"];
const latitude = [models.sequelize.literal("ST_Y(location)"), "latitude"];
gdozot2 marked this conversation as resolved.
Show resolved Hide resolved
const includeOption = [{
model: models.images,
attributes: [longitude, latitude],
}];
const sequelizeQuery = {
attributes: basic_attributes,
where: { story: id },
order: [['indexinstory', 'ASC']],
include: includeOption
};
const chapters = await models.stories_chapters.findAll(sequelizeQuery);
story.dataValues.chapters = chapters;
if (story) {
res.json(story);

} else {
res.status(404).json({ error: 'Aucun chapitre trouvé avec cet ID.' });
}
} catch (error) {
logger.error(error);
res.status(404).json({ error: `Une erreur s'est produite lors de la récupération de la story avec l'ID ${id}.` });
}
};
Expand All @@ -50,13 +53,14 @@ const getStoryById = async (req, res) => {
* @param {*} res
*/
const addStory = async (req, res) => {
let { title, logo_link } = req.body;
const { title, logo_link, description, description_preview } = req.body;

try {
const newStory = await Stories.create({ title, logo_link });
const newStory = await models.stories.create({ title, logo_link, description, description_preview });
res.status(201).json(newStory);

} catch (error) {
logger.error(error);
res.status(500).json({ error: "Une erreur s'est produite lors de l'ajout de la story." });
}
};
Expand All @@ -67,23 +71,28 @@ const addStory = async (req, res) => {
* @param {*} res
*/
const updateStory = async (req, res) => {
let { title, logo_link } = req.body;
const { title, logo_link, description, description_preview }= req.body;

try {
const updatedStory = await Stories.update({ title, logo_link }, {where: {id: req.params.id}});
res.status(201).json(updatedStory);
await models.stories.update({ title, logo_link, description, description_preview }, {where: {id: req.params.id}});
const updatedStory = await models.stories.findByPk(req.params.id);
gdozot2 marked this conversation as resolved.
Show resolved Hide resolved
res.status(200).json(updatedStory);

} catch (error) {
logger.error(error);
res.status(500).json({ error: "Une erreur s'est produite lors de la mis à jour de la story." });
}
};

const deleteStory = async (req, res) =>{
try{
const deletedStory = await Stories.destroy({where: {id: req.params.id}});
res.status(200).json(deletedStory);
await models.stories.destroy({where: {id: req.params.id}});
res.send({
message: "The story was deleted."
});

}catch(error){
logger.error(error);
res.status(500).json({error: "Une erreur c'est produite lors de la supression de la story"});
}
}
Expand Down
44 changes: 44 additions & 0 deletions app/api/stories/stories.delete.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const { resetDatabase } = require('../../../spec/utils/db');
const { setUpGlobalHooks } = require('../../../spec/utils/hooks');
const { createApplicationWithMocks } = require('../../../spec/utils/mocks');
const { expect } = require('../../../spec/utils/chai');
const { testHttpRequest } = require('../../../spec/utils/api');
const { expectNoSideEffects } = require('../../../spec/expectations/side-effects');
const { createStory } = require('../../../spec/fixtures/stories');

// This should be in every integration test file.
setUpGlobalHooks();

describe('DELETE /stories', () => {
let app;

beforeEach(async () => {
await resetDatabase();
({ app } = createApplicationWithMocks());
});

it('Delete a story', async () => {
const { id } = await createStory({
title: "Mon titre",
logo_link: "http://localhost",
description_preview: "abc",
description: "efg"
});
const req = {
method: 'DELETE',
path: `/stories/${id}`,
};

expect(req).to.matchRequestDocumentation();

const res = await testHttpRequest(app, req);

expect(res)
.to.have.status(200)
.and.to.matchResponseDocumentation();

await expectNoSideEffects(app);
gdozot2 marked this conversation as resolved.
Show resolved Hide resolved

});

});
19 changes: 13 additions & 6 deletions app/api/stories/stories.openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
get:
summary: Get all stories
parameters:
- $ref: "#/components/parameters/LanguageParameter"
- name: page
in: query
required: false
Expand All @@ -18,15 +19,17 @@

post:
summary: Add a new story
parameters:
- $ref: "#/components/parameters/LanguageParameter"
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Stories'
responses:
'200':
description: OK
'201':
description: OK
content:
application/json:
schema:
Expand All @@ -45,9 +48,9 @@
'200':
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Stories"
application/json:
schema:
$ref: "#/components/schemas/Stories"
'404':
$ref: "#/components/responses/NotFoundError"
put:
Expand Down Expand Up @@ -86,4 +89,8 @@
type: string
responses:
'200':
description: OK
description: Successful request.
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessMessageResponse"
Loading