From 5759ba79e03029a5b8a064fc7ec2a7db1fed9aae Mon Sep 17 00:00:00 2001 From: Andreas Stephanides Date: Sat, 5 Jan 2019 02:54:50 +0100 Subject: [PATCH] increase test coverage for meetings --- app/models/meeting.rb | 89 +++++++++++--------- app/models/meetingtyp.rb | 3 +- spec/factories/meetings.rb | 8 +- spec/factories/meetingtyps.rb | 6 +- spec/models/meeting_spec.rb | 149 ++++++++++++++++++++++++++++++++- spec/models/meetingtyp_spec.rb | 23 +++++ spec/spec_helper.rb | 2 + spec/support/model_macros.rb | 31 +++---- 8 files changed, 250 insertions(+), 61 deletions(-) diff --git a/app/models/meeting.rb b/app/models/meeting.rb index 847636c..3345d79 100644 --- a/app/models/meeting.rb +++ b/app/models/meeting.rb @@ -1,40 +1,58 @@ + +# coding: utf-8 +# This class represents a single meeting of a group or the whole Fachschaft. +# class Meeting < ActiveRecord::Base - belongs_to :parent, :polymorphic=>true, touch: true - belongs_to :meetingtyp attr_accessible :desc, :intern, :name, :parent_id, :parent_type, :calentry,:calentry_attributes, :meetingtyp_id - + + # Meeting can belong to different kind of parents e.g. topics + belongs_to :parent, :polymorphic=>true, touch: true + # Each meeting should have a type, for more information see MeetingTyp + belongs_to :meetingtyp + # Belongs to a news article, that is usually the Announcement of that meeting belongs_to :neuigkeit, touch: true + # has one protocol of type Document, which is of typ=10=protocol has_one :protocol, :class_name=>'Document', :conditions=>{:typ=>10}, :as=>:parent + # has one agenda of type Document has_one :agenda , :as=>:parent,:conditions=>{:typ=>11}, :class_name=>'Document' + # has one calentry which contains the date and time of this meeting has_one :calentry, as: :object, :dependent=> :destroy + # has one calendar through the meetingtyp, thus each meeting is put into a calendar has_one :calendar, :through=>:meetingtyp + # has one rubrik, thus it is associated to a rubrik has_one :rubrik, :through=>:meetingtyp + + # scope upcomming only contains meetings in the future and 1 hour into the past scope :upcomming, includes(:calentry).where("calentries.start>?",1.hour.ago) default_scope includes(:calentry).order("calentries.start").reverse_order accepts_nested_attributes_for :calentry -# validate :agenda, :presence=>true -# validate :protocol, :presence=>true + + # Each meeting is required to have a parent otherwise it will not be shown anywhere on the website validate :parent, :presence=>true + # Each meeting needs a calendar entry validate :calentry, :presence=>true + + + # before each validation fix the calendar entry such that it is always before_validation :fix_calentry + # title is an alias for text def title self.text end - + + # Text is a text representation of the meeting def text - unless self.meetingtyp.try(:name).to_s.empty? - t = self.meetingtyp.name.to_s+", " - else - t="" - t = parent.title.to_s + ", " if self.name.empty? - end + t = self.meetingtyp.try(:name) || self.parent.try(:title) || "" + t = t + ", " unless t.empty? t= t+ self.name.to_s - # t = t + " " + I18n.l(self.calentry.start) unless self.calentry.nil? t = t +" "+ I18n.t("date.am")+" "+ self.calentry.text unless self.calentry.nil? t end + + # Creante an anouncement with an author + # @param user is the author def create_announcement(user) if self.neuigkeit.nil? n = Neuigkeit.new @@ -48,32 +66,40 @@ class Meeting < ActiveRecord::Base self.neuigkeit= n end end + + # Update the title of the announcement to the text of this meeting + # @returns [true] if save was successful def update_announcement n=self.neuigkeit n.title=self.text n.save end + + # fixing the calendar entry and the calendar + # most importantly the calendar of the calentry def fix_calentry self.calentry.object=self unless self.calentry.nil? self.calentry.calendar = self.meetingtyp.rubrik.calendar end + def public? ! (self.intern) end + + # Create a Document that is a protocol for the meeting def create_protocol - if self.protocol.nil? + if self.protocol.nil? # if no protocol exists d=Document.new d.typ=10 d.name="Protokoll" - unless self.meetingtyp.protocol.nil? - d.text=self.meetingtyp.protocol.text - end d.save self.protocol=d end - + # what happens if a protocol already exists? end + + # Create a calender entry for this meeting def create_calentry if self.calentry.nil? ce =Calentry.new @@ -86,9 +112,6 @@ class Meeting < ActiveRecord::Base d=Document.new d.typ=11 d.name="Agenda" - unless self.meetingtyp.agenda.nil? - d.text=self.meetingtyp.agenda.text - end d.save self.agenda=d end @@ -112,27 +135,17 @@ class Meeting < ActiveRecord::Base def update_time_from_protocol st= /Beginn[\s:]*([^<>]*)/.match(self.protocol.text)[1].to_s - st= /Anfang[\s:]*([^<>]*)/.match(self.protocol.text)[1].to_s if st.empty? - self.calentry.start=(self.calentry.start.to_date.to_s + " " +st).to_datetime unless st.empty? - st= /Ende[\s:]*([^<>]*)/.match(self.protocol.text)[1].to_s - self.calentry.ende=(self.calentry.ende.to_date.to_s + " " +st).to_datetime unless st.empty? + st= /Anfang[\s:]*([^<>]*)/.match(self.protocol.text)[1].to_s if st.nil? || st.empty? + self.calentry.start=(self.calentry.start.to_date.to_s + " " +st).to_datetime unless st.nil? || st.empty? + st= /Ende[\s:]*([^<>]*)/.match(self.protocol.text).try(:second).try(:to_s ) + self.calentry.ende=(self.calentry.ende.to_date.to_s + " " +st).to_datetime unless st.nil? || st.empty? end def agenda_text - unless self.agenda.nil? - t= self.agenda.text - else - t= "" - end - t + return self.agenda.try(:text) || "" end def protocol_text - unless self.protocol.nil? - t= self.protocol.text - else - t= "" - end - t -end + return self.protocol.try(:text) || "" + end searchable do text :text diff --git a/app/models/meetingtyp.rb b/app/models/meetingtyp.rb index 48e114d..48b10b8 100644 --- a/app/models/meetingtyp.rb +++ b/app/models/meetingtyp.rb @@ -1,7 +1,8 @@ class Meetingtyp < ActiveRecord::Base attr_accessible :agendaintern, :desc, :name, :protocolintern, :rubrik_id, :picture belongs_to :rubrik - validate :rubrik, :presence=>true + validates :rubrik, :presence=>true + validates :name, :presence=>true has_many :meetings has_one :calendar, through: :rubrik has_one :protocol, :class_name=>'Document', :conditions=>{:typ=>10}, :as=>:parent diff --git a/spec/factories/meetings.rb b/spec/factories/meetings.rb index 8e0726f..ff6c4d2 100644 --- a/spec/factories/meetings.rb +++ b/spec/factories/meetings.rb @@ -1,10 +1,10 @@ FactoryGirl.define do factory :meeting do name "MyString" -desc "MyText" -parent nil -intern false -meetingtyp nil + desc "MyText" + parent nil + intern false + meetingtyp nil end end diff --git a/spec/factories/meetingtyps.rb b/spec/factories/meetingtyps.rb index 6538467..206530f 100644 --- a/spec/factories/meetingtyps.rb +++ b/spec/factories/meetingtyps.rb @@ -1,9 +1,9 @@ FactoryGirl.define do factory :meetingtyp do name "MyString" -desc "MyText" -agendaintern false -protocolintern false + desc "MyText" + agendaintern false + protocolintern false end end diff --git a/spec/models/meeting_spec.rb b/spec/models/meeting_spec.rb index 2e72528..aa5ad97 100644 --- a/spec/models/meeting_spec.rb +++ b/spec/models/meeting_spec.rb @@ -1,5 +1,152 @@ require 'spec_helper' RSpec.describe Meeting, :type => :model do - pending "add some examples to (or delete) #{__FILE__}" + let(:user){FactoryGirl.create(:user)} + let(:rubrik) {FactoryGirl.create(:rubrik)} + let(:calendar){FactoryGirl.create(:calendar, rubrik_id: rubrik.id)} + let(:calentry){FactoryGirl.build(:calentry, calendar_id: calendar.id, typ: 2)} + let(:meetingtyp){FactoryGirl.create(:meetingtyp, rubrik_id: rubrik.id)} + let(:meeting){FactoryGirl.build(:meeting, meetingtyp_id: meetingtyp.id)} + + it "should be created" do + meeting.calentry=calentry + expect(meeting).to be_valid + expect(meeting.save).to be true + end + it "should have a calendar" do + meeting.calentry=calentry + expect(meeting.calendar).not_to be_nil + end + it "should be able to create a calentry" do + meeting.create_calentry + meeting.calentry.start=1.hour.ago + meeting.calentry.dauer=7 + expect(meeting).to be_valid + end + it "should be creating a calentry typ 2" do + meeting.create_calentry + expect(meeting.calentry.typ).to be 2 + end + it "should be having an alias title for text" do + expect(meeting.title).to eq(meeting.text) + end + it "should have a text that includes the name" do + expect(meeting.title).to match meeting.name + end + it " creates a neuigkeit that is valid" do + expect(meeting.neuigkeit).to be_nil + meeting.create_announcement(user) + expect(meeting.neuigkeit.class).to eq(Neuigkeit) + expect(meeting.neuigkeit).to be_valid + end + it "fixes calentry before validation" do + calentry.calendar=nil + meeting.calentry=calentry + meeting.valid? + expect(meeting.calentry.calendar).to be meeting.meetingtyp.rubrik.calendar + end + it "updates the announcement if there is one" do + meeting.calentry=calentry + + expect(meeting.neuigkeit).to be_nil + meeting.create_announcement(user) + meeting.name="asdflkjhasdflkj" + meeting.save + meeting.update_announcement + expect(meeting.neuigkeit.title).to match meeting.name + end + it "doesn't create an announcement by changing the name" do + meeting.calentry=calentry + expect(meeting.neuigkeit).to be_nil + meeting.name="asdflkjhasdflkj" + meeting.save + expect(meeting.neuigkeit).to be_nil + end + it "can create a protocol" do + expect(meeting.protocol).to be_nil + meeting.create_protocol + expect(meeting.protocol).not_to be_nil + end + it "creates a protocol only once" do + meeting.create_protocol + p=meeting.protocol + meeting.protocol.text="TestTextTestTextForProtocol" + meeting.create_protocol + expect(meeting.protocol).to be p + expect(meeting.protocol.text).to match "TestTextTestTextForProtocol" + end + it "can create a calendar entry" do + expect(meeting.calentry).to be_nil + meeting.create_calentry + expect(meeting.calentry).not_to be_nil + + end + it "can create an agenda" do + meeting.calentry=calentry + + meeting.create_agenda + a=meeting.agenda + meeting.agenda.text="TestTextTestTextForProtocol" + meeting.create_agenda + expect(meeting.agenda).to be a + expect(meeting.agenda.text).to match "TestTextTestTextForProtocol" + end + it "can be created with date and typ" do + meeting2=Meeting.new_with_date_and_typ(nil, Date.today, meetingtyp) + expect(meeting2.calentry).not_to be_nil + expect(meeting2.meetingtyp).to be meetingtyp + end + it "gets empty text for nil protocol" do + expect(meeting.protocol_text).to eq("") + end + it "gets empty text for nil agenda" do + expect(meeting.agenda_text).to eq("") + end + + it "can safly access protocol text" do + meeting.create_protocol + meeting.protocol.text="TestTextTest TextForProtocol" + expect(meeting.protocol_text).to eq("TestTextTest TextForProtocol") + end + it "can safly access agenda text" do + meeting.create_agenda + meeting.agenda.text="TestTextTest TextForProtocol" + expect(meeting.agenda_text).to eq("TestTextTest TextForProtocol") + end + it "is public by default" do + expect(meeting).to be_public + end + it "is not public if intern" do + meeting.intern=true + expect(meeting).not_to be_public + end + it "has a divid" do + meeting.calentry=calentry + meeting.save + expect(meeting.divid).to match "meeting" + expect(meeting.divid).to match meeting.id.to_s + end + it "can find start and end of a meeting by 'Beginn' und 'Ende'" do + meeting.calentry=calentry + calentry.start=2.hours.ago + meeting.create_protocol + meeting.protocol.text="Beginn: " + 1.hours.ago.to_s + meeting.update_time_from_protocol + expect(calentry.start).to be_within(1.minute).of 1.hours.ago + + end + it "has a text even without meetingtyp" do + meeting.meetingtyp=nil + meeting.parent=nil + meeting.name="sdf" + expect(meeting.text).to match("sdf") + end + it "has an empty text without meetingtyp, parent, calentry or name" do + meeting.meetingtyp=nil + meeting.parent=nil + meeting.calentry=nil + meeting.name="" + expect(meeting.text).to eq("") + end end + diff --git a/spec/models/meetingtyp_spec.rb b/spec/models/meetingtyp_spec.rb index 09545ef..ff7afdc 100644 --- a/spec/models/meetingtyp_spec.rb +++ b/spec/models/meetingtyp_spec.rb @@ -2,4 +2,27 @@ require 'spec_helper' RSpec.describe Meetingtyp, :type => :model do pending "add some examples to (or delete) #{__FILE__}" + let(:rubrik) {FactoryGirl.create(:rubrik)} + let(:meetingtyp){FactoryGirl.build(:meetingtyp, rubrik_id: rubrik.id)} + it "should be created" do + expect(meetingtyp).to be_valid + expect(meetingtyp.save).to be true + end + it "should not be valid without rubrik" do + meetingtyp.rubrik=nil + expect(meetingtyp.rubrik).to be_nil + expect(meetingtyp).not_to be_valid + expect(meetingtyp.save).to be_falsey + end + it "should not be valid without a name" do + meetingtyp.name=nil + expect(meetingtyp).not_to be_valid + end + + it "should return name for text" do + expect(meetingtyp.text).to be meetingtyp.name + end + + + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f283b59..8423afd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,6 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' +require 'simplecov' +SimpleCov.start ENV["RAILS_ENV"] ||= 'test' require 'rbconfig' diff --git a/spec/support/model_macros.rb b/spec/support/model_macros.rb index 5da7d1d..7b7dd77 100644 --- a/spec/support/model_macros.rb +++ b/spec/support/model_macros.rb @@ -1,18 +1,21 @@ module ModelMacros def let_studium_lva - let(:studium) {FactoryGirl.create(:studium)} - let(:modulgruppe){FactoryGirl.create(:modulgruppe,studium_id: studium.id)} - let(:modul) do - m=FactoryGirl.build(:other_modul); - m.modulgruppen << modulgruppe - m.save! - m - end - let(:lva) do - l=FactoryGirl.build(:lva) - l.modul << modul - l.save! - l - end + let(:studium) {FactoryGirl.create(:studium)} + + let(:zerosemester) {FactoryGirl.create(:zero_semester,studium_id: studium.id)} + let(:firstsemester) {FactoryGirl.create(:first_semester)} + let(:modulgruppe){FactoryGirl.create(:modulgruppe,studium_id: studium.id)} + let(:modul) do + m=FactoryGirl.build(:other_modul) + m.modulgruppen << modulgruppe + m.save! + m + end + let(:lva) do + l=FactoryGirl.build(:lva) + l.modul << modul + l + end + end end