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

EVA-193 Les zones déposables du jeu sont automatiquement utilisées depuis le masque #1686

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/models/application_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ def cdn_for(attachment)

ApplicationController.helpers.cdn_for(attachment)
end

def fichier_encode_base64(attachment)
file_content = attachment.download
ApplicationController.helpers.fichier_encode_en_base64(file_content)
end
end
5 changes: 0 additions & 5 deletions app/models/question_clic_dans_image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,4 @@ def valide_zone_cliquable_avec_reponse
errors.add(:zone_cliquable, "doit contenir la classe 'bonne_reponse'")
throw(:abort)
end

def fichier_encode_base64(attachment)
file_content = attachment.download
ApplicationController.helpers.fichier_encode_en_base64(file_content)
end
end
6 changes: 3 additions & 3 deletions app/models/question_glisser_deposer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ class QuestionGlisserDeposer < Question

def as_json(_options = nil)
json = base_json
json['zone_depot_url'] = zone_depot if zone_depot.attached?
json['zone_depot_url'] = fichier_encode_base64(zone_depot) if zone_depot.attached?
json.merge!(json_audio_fields, reponses_fields)
end

private

def base_json
slice(:id, :nom_technique, :description).tap do |json|
json['type'] = 'glisser-deposer-billets'
json['type'] = 'glisser-deposer'
json['illustration'] = cdn_for(illustration) if illustration.attached?
json['modalite_reponse'] = transcription_modalite_reponse&.ecrit
json['intitule'] = transcription_intitule&.ecrit
Expand All @@ -37,7 +37,7 @@ def base_json
def reponses_fields
reponses_non_classees = reponses.map do |reponse|
illustration_url = cdn_for(reponse.illustration) if reponse.illustration.attached?
reponse.slice(:id, :position, :position_client).merge(
reponse.slice(:id, :position, :nom_technique, :position_client).merge(
'illustration' => illustration_url
)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- 📄 Standard : https://www.notion.so/captive/Le-cadrage-technique-dbb611e45f114737a6b14745caa584e9?pvs=4 -->
# Les zones déposables du jeu sont automatiquement utilisées depuis le masque

> [EVA-193](https://captive-team.atlassian.net/browse/EVA-193)

## Backend

- Envoyer au front les données nécessaires au paramétrage dans le json d'une question GlisserDeposer
```ruby
json['zone_depot_url'] = zone_depot if zone_depot.attached?
```
- Restituer le fichier de test `models/question_glisser_deposer_spec.rb` comme avant
- Modifier le type de QuestionGlisserDeposer et envoyé au front le type `glisser-deposer`

# Frontend

- Cleaner les données en dur de `numeratie.js` et `rattrapage.js` qui ne sont plus utiles
- Si question.zone_depot_url retourner l'extensionVue `glisser-deposer-depot-multiple` sinon retourner `glisser-deposer-billets`
- Renommer le composant `GlisserDeposerDepotMultiple` en `GlisserDeposerMultiple`
- Renommer le composant `GlisserDeposerBillets` en `GlisserDeposerSimple`
- Gérer le calcul des points en vérifiant que chaque élement est déposé dans la zone-depot qui contient la class avec le nom technique de la réponse `zone-depot--nomTechniqueReponse`
219 changes: 57 additions & 162 deletions spec/models/question_glisser_deposer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,184 +2,79 @@

require 'rails_helper'

describe 'Admin - Question Glisser Deposer', type: :feature do
before(:each) { se_connecter_comme_superadmin }

describe 'show' do
let!(:question) do
create :question_glisser_deposer, libelle: 'Libellé de la question'
end
let!(:transcription) do
create :transcription, question_id: question.id, ecrit: 'Comment ça va ?'
end

before(:each) { visit admin_question_glisser_deposer_path(question) }

it 'affiche le libellé de la question et la transcription associée' do
expect(page).to have_content 'Libellé de la question'
expect(page).to have_content 'Comment ça va ?'
end
describe QuestionGlisserDeposer, type: :model do
let!(:question) do
create(:question_glisser_deposer,
illustration: Rack::Test::UploadedFile.new(
Rails.root.join('spec/support/programme_tele.png')
),
zone_depot: Rack::Test::UploadedFile.new(
Rails.root.join('spec/support/N1Pse1-zone-depot-valide.svg')
))
end

describe 'index' do
let!(:question) do
create :question_glisser_deposer
end
let!(:transcription) do
create :transcription, question_id: question.id, ecrit: 'Comment ça va ?'
end

before(:each) { visit admin_questions_glisser_deposer_path }

it do
expect(page).to have_content 'Comment ça va ?'
end
let(:json) { question.as_json }
let!(:reponse1) do
create(:choix, :avec_illustration, :bon, question_id: question.id, position_client: 2)
end
let!(:reponse2) { create(:choix, :avec_illustration, :bon, question_id: question.id) }
let!(:modalite) do
create(:transcription, :avec_audio, question_id: question.id,
categorie: :modalite_reponse)
end

describe 'création' do
before(:each) do
visit new_admin_question_glisser_deposer_path
end

context 'sans transcriptions' do
before(:each) do
fill_in :question_glisser_deposer_libelle, with: 'Question'
fill_in :question_glisser_deposer_nom_technique, with: 'question'
end

it 'créé une nouvelle question' do
expect { click_on 'Créer' }.to(change { Question.count })
expect(Question.first.transcriptions).to be_empty
end
end

context 'quand une transcription pour intitule est ajouté' do
before(:each) do
fill_in :question_glisser_deposer_libelle, with: 'Question'
fill_in :question_glisser_deposer_nom_technique, with: 'question'
fill_in :question_glisser_deposer_transcriptions_attributes_0_ecrit, with: 'Intitulé'
click_on 'Créer'
end

it do
expect(Question.first.transcriptions.count).to eq 1
expect(Question.first.transcription_intitule&.ecrit).to eq 'Intitulé'
end
end

context 'quand une transcription pour modalité réponse est ajoutée' do
before(:each) do
fill_in :question_glisser_deposer_libelle, with: 'Question'
fill_in :question_glisser_deposer_nom_technique, with: 'question'
fill_in :question_glisser_deposer_transcriptions_attributes_1_ecrit, with: 'Consigne'
click_on 'Créer'
end
it { is_expected.to have_many(:reponses).with_foreign_key(:question_id) }
it { is_expected.to have_one_attached(:zone_depot) }

it do
expect(Question.first.transcriptions.count).to eq 1
expect(Question.first.transcription_modalite_reponse&.ecrit).to eq 'Consigne'
end
describe '#as_json' do
it 'serialise les champs' do
expect(json.keys).to match_array(%w[id intitule audio_url nom_technique
description illustration modalite_reponse type
reponsesNonClassees zone_depot_url])
expect(json['type']).to eql('glisser-deposer')
expect(json['modalite_reponse']).to eql(modalite.ecrit)
expect(json['illustration']).to eql(Rails.application.routes.url_helpers.url_for(
question.illustration
))
expect(json['zone_depot_url']).to start_with('data:image/svg+xml;base64,')
end

context 'quand une illustration est ajoutée' do
before(:each) do
fill_in :question_glisser_deposer_libelle, with: 'Question'
fill_in :question_glisser_deposer_nom_technique, with: 'question'
attach_file(:question_glisser_deposer_illustration,
Rails.root.join('spec/support/programme_tele.png'))
click_on 'Créer'
end

describe 'les reponsesNonClassees' do
it do
expect(Question.first.illustration.attached?).to eq true
expect(json['reponsesNonClassees'].size).to be(2)
expect(json['reponsesNonClassees'].first['illustration']).not_to be_nil
expect(json['reponsesNonClassees'].first['position']).to be(1)
expect(json['reponsesNonClassees'].first['position_client']).to be(2)
expect(json['reponsesNonClassees'].first['nom_technique']).to eql(reponse1.nom_technique)
end
end
end

describe 'modification' do
let!(:question) do
create :question_glisser_deposer,
illustration: Rack::Test::UploadedFile.new(
Rails.root.join('spec/support/programme_tele.png')
)
end
let!(:transcription) do
create :transcription, question_id: question.id, ecrit: 'Comment ça va ?'
end

let!(:modalite_reponse) do
create :transcription, :avec_audio, question_id: question.id, ecrit: 'Comment ça va ?',
categorie: :modalite_reponse
end

context "quand l'admin supprime l'écrit d'une transcription et qu'il n'y a pas d'audio" do
before(:each) do
visit edit_admin_question_glisser_deposer_path(question)
fill_in :question_glisser_deposer_transcriptions_attributes_0_ecrit, with: nil
end

it 'supprime la transcription' do
expect(Question.first.transcriptions.count).to eq 2
click_on 'Enregistrer'
expect(Question.first.transcriptions.count).to eq 1
end
end

context "quand l'admin coche supprimer l'illustration" do
before(:each) do
visit edit_admin_question_glisser_deposer_path(question)
check 'question_glisser_deposer_supprimer_illustration'
end

it "supprime l'illustration" do
expect(question.illustration.attached?).to eq true
click_on 'Enregistrer'
question.reload
expect(question.illustration.attached?).to eq false
end
describe 'validations' do
let(:question) do
build(:question_glisser_deposer)
end

context "quand l'admin coche supprimer l'audio de l'intitulé" do
before(:each) do
Question.first.transcriptions.find_by(categorie: :intitule)
.update(audio: Rack::Test::UploadedFile.new(
Rails.root.join('spec/support/alcoolique.mp3')
))
visit edit_admin_question_glisser_deposer_path(question)
check 'question_glisser_deposer_supprimer_audio_intitule'
end

it "supprime l'audio" do
expect(
Question.first.transcriptions.find_by(categorie: :intitule).audio.attached?
).to eq true
click_on 'Enregistrer'
question.reload
expect(
Question.first.transcriptions.find_by(categorie: :intitule).audio.attached?
).to eq false
context 'avec un attachment au format svg' do
it 'est valide' do
question.zone_depot.attach(
io: Rails.root.join('spec/support/accessibilite-sans-reponse.svg').open,
filename: 'valid.svg',
content_type: 'image/svg+xml'
)
expect(question).to be_valid
end
end

context "quand l'admin coche supprimer l'audio de la consigne" do
before(:each) do
Question.first.transcriptions.find_by(categorie: :modalite_reponse)
.update(audio: Rack::Test::UploadedFile.new(
Rails.root.join('spec/support/alcoolique.mp3')
))
visit edit_admin_question_glisser_deposer_path(question)
check 'question_glisser_deposer_supprimer_audio_modalite_reponse'
end

it "supprime l'audio" do
expect(
Question.first.transcriptions.find_by(categorie: :modalite_reponse).audio.attached?
).to eq true
click_on 'Enregistrer'
question.reload
expect(
Question.first.transcriptions.find_by(categorie: :modalite_reponse).audio.attached?
).to eq false
context "avec un attachement d'un autre format" do
it "n'est pas valide" do
question.zone_depot.attach(
io: Rails.root.join('spec/support/programme_tele.png').open,
filename: 'invalid.png',
content_type: 'image/png'
)
expect(question).not_to be_valid
erreur = question.errors[:zone_depot]
expect(erreur).to include("n'est pas un format de fichier valide")
end
end
end
Expand Down