Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
IvaKop committed Nov 14, 2023
2 parents a8f98a7 + 81ce142 commit 6844f29
Show file tree
Hide file tree
Showing 206 changed files with 5,250 additions and 1,371 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ workflows:
compose_file: docker-compose-production-benelux.yml
stack_name: cl2-prd-bnlx-stack
env_file: ".env-production-benelux"
cluster_name: "prd"
cluster_name: "eu"
- back-deploy-to-swarm:
name: Deploy to Canada
requires:
Expand Down
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,23 @@ e2e-ci-env-run-test:
cd e2e && \
docker-compose run --rm --name cypress_run front npm run cypress:run -- --config baseUrl=http://e2e.front:3000 --spec ${spec}

e2e-ci-env-db-dump:
cd e2e && \
docker compose exec postgres pg_dumpall -c -U postgres > dump.sql

e2e-ci-env-db-restore:
cd e2e && \
docker compose exec postgres psql -U postgres -d cl2_back_development -c "SELECT 1" 1> /dev/null && \
docker compose exec postgres psql -U postgres -d cl2_back_development -c "DROP SCHEMA IF EXISTS e2e_front,public CASCADE" 1> /dev/null 2> /dev/null && \
docker compose exec postgres psql -U postgres -d cl2_back_development -c "CREATE SCHEMA public" && \
cat dump.sql | docker compose exec -T postgres psql --quiet -U postgres 1> /dev/null 2> /dev/null

e2e-ci-env-reproduce-flaky-test:
for i in $(shell seq 1 10); do \
make e2e-ci-env-db-restore && \
make e2e-ci-env-run-test spec="${spec}"; \
done

# =================
# CircleCI
# =================
Expand Down
2 changes: 1 addition & 1 deletion back/app/models/idea.rb
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def input_term
else
now = Time.zone.now
phases_with_ideas = phases.select(&:can_contain_ideas?).sort_by(&:start_at)
first_past_phase_with_ideas = phases_with_ideas.reverse_each.detect { |phase| phase.end_at <= now }
first_past_phase_with_ideas = phases_with_ideas.reverse_each.detect { |phase| phase.end_at&.<= now }
if first_past_phase_with_ideas
first_past_phase_with_ideas.input_term
else # now is before the first phase with ideas
Expand Down
3 changes: 2 additions & 1 deletion back/app/models/notifications/voting_basket_submitted.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def self.make_notifications_on(activity)
[new(
recipient_id: recipient_id,
basket: basket,
project: basket.participation_context.project
project: basket.participation_context.project,
phase: basket.participation_context.phase? ? basket.participation_context : nil
)]
else
[]
Expand Down
36 changes: 34 additions & 2 deletions back/app/models/phase.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ class Phase < ApplicationRecord
validates :title_multiloc, presence: true, multiloc: { presence: true }
validates :description_multiloc, multiloc: { presence: false, html: true }
validates :campaigns_settings, presence: true
validates :start_at, :end_at, presence: true
validates :start_at, presence: true
validate :validate_end_at
validate :validate_previous_blank_end_at
validate :validate_start_at_before_end_at
validate :validate_belongs_to_timeline_project
validate :validate_no_other_overlapping_phases
Expand Down Expand Up @@ -112,6 +114,17 @@ def permission_scope
self
end

def last_phase?
phases = Phase.where(project_id: project_id)
return true if phases.blank?

start_at.present? && start_at >= phases.maximum(:start_at)
end

def previous_phase_end_at_updated?
@previous_phase_end_at_updated || false
end

private

def sanitize_description_multiloc
Expand All @@ -124,6 +137,25 @@ def sanitize_description_multiloc
self.description_multiloc = service.linkify_multiloc(description_multiloc)
end

def validate_end_at
return if end_at.present? || last_phase?

errors.add(:end_at, message: 'cannot be blank unless it is the last phase')
end

# If a previous phase has a blank end_at, update it and validate that the end date is 2 days after
def validate_previous_blank_end_at
previous_phase = TimelineService.new.previous_phase(self)
if previous_phase && previous_phase.end_at.blank?
if start_at < (previous_phase.start_at + 2.days)
errors.add(:start_at, message: 'must be 2 days after the start of the last phase')
else
previous_phase.update!(end_at: (start_at - 1.day))
@previous_phase_end_at_updated = true
end
end
end

def validate_campaigns_settings_keys_and_values
return if campaigns_settings.blank?

Expand All @@ -150,7 +182,7 @@ def validate_belongs_to_timeline_project
def validate_no_other_overlapping_phases
ts = TimelineService.new
ts.other_project_phases(self).each do |other_phase|
next unless start_at.present? && end_at.present? && ts.overlaps?(self, other_phase)
next unless ts.overlaps?(self, other_phase)

errors.add(:base, :has_other_overlapping_phases,
message: 'has other phases which overlap in start and end date')
Expand Down
4 changes: 4 additions & 0 deletions back/app/serializers/web_api/v1/phase_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ class WebApi::V1::PhaseSerializer < WebApi::V1::ParticipationContextSerializer
TextImageService.new.render_data_images object, :description_multiloc
end

attribute :previous_phase_end_at_updated do |object|
object.previous_phase_end_at_updated?
end

belongs_to :project

has_one :user_basket, if: proc { |object, params|
Expand Down
15 changes: 8 additions & 7 deletions back/app/services/cl2_data_listing_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ def cl2_schema_models
views = ActiveRecord::Base.connection.execute(
"SELECT table_name FROM information_schema.tables WHERE table_type = 'VIEW'"
).pluck('table_name')
ActiveRecord::Base.descendants.select do |claz|
[
*ActiveRecord::Base.subclasses.map(&:name),
Tenant.name
].exclude? claz.name
end.select do |claz|
views.exclude? claz.table_name
subclasses = [
*ActiveRecord::Base.subclasses.map(&:name),
Tenant.name
]
ActiveRecord::Base.descendants.reject do |claz|
subclasses.include?(claz.name) ||
views.include?(claz.table_name) ||
claz.abstract_class
end
end

Expand Down
30 changes: 21 additions & 9 deletions back/app/services/timeline_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def future_phases(project, time = Time.now)
def past_phases(project, time = Time.now)
date = time.in_time_zone(AppConfiguration.instance.settings('core', 'timezone')).to_date
project.phases.select do |phase|
phase.end_at < date
phase.end_at&.< date
end
end

Expand All @@ -20,15 +20,15 @@ def current_phase(project, time = Time.now)
return unless project.timeline?

project.phases.find do |phase|
phase.start_at <= date && phase.end_at >= date
phase.start_at <= date && (phase.end_at.nil? || phase.end_at >= date)
end
end

def phase_is_complete?(participation_context, time = Time.now)
return false unless participation_context.phase?

date = time.in_time_zone(AppConfiguration.instance.settings('core', 'timezone')).to_date
participation_context.end_at <= date
participation_context.end_at.present? && participation_context.end_at <= date
end

def current_or_last_can_contain_ideas_phase(project, time = Time.now)
Expand All @@ -41,7 +41,7 @@ def current_or_last_can_contain_ideas_phase(project, time = Time.now)
ideation_phases = phases.select(&:can_contain_ideas?)
return if ideation_phases.blank?

current_phase = ideation_phases.find { |phase| phase.start_at <= date && date <= phase.end_at }
current_phase = ideation_phases.find { |phase| phase.start_at <= date && (phase.end_at.nil? || date <= phase.end_at) }
current_phase || ideation_phases.last
end

Expand All @@ -50,7 +50,7 @@ def current_and_future_phases(project, time = Time.now)
return unless project.timeline?

project.phases.select do |phase|
phase.end_at >= date
phase.end_at.nil? || phase.end_at >= date
end
end

Expand All @@ -59,6 +59,10 @@ def in_active_phase?(idea)
end

def overlaps?(phase1, phase2)
return true if (phase1.start_at.blank? && phase1.end_at.blank?) || (phase2.start_at.blank? && phase2.end_at.blank?)
return (phase1.start_at <= phase2.start_at) if phase1.end_at.blank?
return (phase2.start_at <= phase1.start_at) if phase2.end_at.blank?

!((phase1.end_at.to_date < phase2.start_at.to_date) || (phase2.end_at.to_date < phase1.start_at.to_date))
end

Expand All @@ -70,10 +74,10 @@ def timeline_active(project)
today = Time.now.in_time_zone(AppConfiguration.instance.settings('core', 'timezone')).to_date
if project.continuous? || project.phases.blank?
nil
elsif today > project.phases.maximum(:end_at)
:past
elsif today < project.phases.minimum(:start_at)
:future
elsif project.phases.last.end_at.present? && today > project.phases.maximum(:end_at)
:past
else
:present
end
Expand All @@ -83,13 +87,17 @@ def timeline_active_on_collection(projects)
today = Time.now.in_time_zone(AppConfiguration.instance.settings('core', 'timezone')).to_date
starts = Phase.where(project: projects).group(:project_id).minimum(:start_at)
ends = Phase.where(project: projects).group(:project_id).maximum(:end_at)

# For any projects open end dates?
open_end_starts = Phase.where(project: projects, end_at: nil).group(:project_id).maximum(:start_at)

projects.to_h do |project|
active = if project.continuous? || project.phases.blank?
nil
elsif today > ends[project.id]
:past
elsif today < starts[project.id]
:future
elsif open_end_starts[project.id].blank? && today > ends[project.id]
:past
else
:present
end
Expand All @@ -101,4 +109,8 @@ def phase_number(phase)
phase_ids = phase.project.phase_ids
phase_ids.find_index(phase.id) + 1
end

def previous_phase(phase)
Phase.where('project_id = ? AND start_at < ?', phase.project_id, phase.start_at).order(start_at: :desc).take
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddMembershipsCountToGroups < ActiveRecord::Migration[7.0]
def change
add_column :groups, :memberships_count, :integer, null: false, default: 0, if_not_exists: true
end
end
3 changes: 2 additions & 1 deletion back/db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7960,6 +7960,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20230915391649'),
('20230927135924'),
('20231003095622'),
('20231018083110');
('20231018083110'),
('20231109101517');


Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,20 @@
end
end

context 'and its last phase has an open end date' do
let(:end_date) { nil }

it 'the project is not finished', :aggregate_failures do
expect(described_class.count).to eq(1)

project_status = described_class.first
expect(project_status.dimension_project_id).to eq(project.id)
expect(project_status.timestamp.floor).to eq(project.admin_publication.updated_at.floor)
expect(project_status.status).to eq('published')
expect(project_status.finished).to be(false)
end
end

include_examples 'shared examples'
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def exposed_config_parameters
def profile_to_uid(auth)
case config[:identity_source]
when DK_MIT_ID
auth['uuid']
auth['uid']
else
raise "Unsupported identity source #{config[:identity_source]}"
end
Expand Down
Loading

0 comments on commit 6844f29

Please sign in to comment.