<p>Microcosms is a feature to support (local) groups of mappers and the events they participate in.</p>
<p>All of this code is tested using cucumber.  To test run bundle install; bundle exec rake cucumber.</p>

<hr>

<h4>You can view, comment on, or merge this pull request online at:</h4>
<p>  <a href='https://github.com/openstreetmap/openstreetmap-website/pull/2390'>https://github.com/openstreetmap/openstreetmap-website/pull/2390</a></p>

<h4>Commit Summary</h4>
<ul>
  <li>add cucumber-rails and generate the installation</li>
  <li>Add microcosm model and controller.</li>
  <li>regular users should not be able to edit the microcosm</li>
  <li>move method</li>
  <li>Add a list of all microcosms.</li>
  <li>Allow user to join microcosm.  Use friendly_id instead of show_by_key.  Replace microcosm.key with microcosm.slug.</li>
  <li>Replace singular links with a list of links.</li>
  <li>Users may join microcosms multiple times, but only once per role.</li>
  <li>reorder</li>
  <li>add location to microcosm</li>
  <li>Administrators can create and edit microcosms.</li>
  <li>remove useless step definition</li>
  <li>move "new" link to the header</li>
  <li>Organizers can edit their microcosms.  Admin can promote members to organizers (first admin).</li>
  <li>Add events.</li>
  <li>row layout</li>
  <li>make event form like user account form</li>
  <li>Promote users from the microcosm members page, not the microcosm page, so we can display users better.</li>
  <li>Put members on cards</li>
  <li>Create show_events page and put link to "new event" over there.  Join button is available to non-signed in users which should redirect to login.</li>
  <li>User can rsvp</li>
  <li>Allow user to cancel their intention to attend an event.</li>
  <li>Not all members are organizers</li>
  <li>Add attendees of an event, reformat some dates</li>
  <li>Add links to microcosm</li>
  <li>Add diary entries of members of the microcosm</li>
  <li>Add sample map of location for event.</li>
  <li>Add sample directions</li>
  <li>Allow :role field for microcosm_member form submission.  Gets the last test passing.</li>
  <li>Enable organizer to promote a member.</li>
  <li>Add Design.md.</li>
</ul>

<h4>File Changes</h4>
<ul>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-0">Design.md</a>
    (1)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-1">Gemfile</a>
    (6)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-2">Gemfile.lock</a>
    (37)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-3">app/abilities/ability.rb</a>
    (9)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-4">app/assets/images/dc_library.png</a>
    (0)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-5">app/assets/images/microcosm_dc.png</a>
    (0)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-6">app/assets/javascripts/event_attendances.coffee</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-7">app/assets/javascripts/events.coffee</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-8">app/assets/javascripts/microcosm_member.coffee</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-9">app/assets/javascripts/microcosms.coffee</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-10">app/assets/stylesheets/event_attendances.scss</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-11">app/assets/stylesheets/events.scss</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-12">app/assets/stylesheets/microcosm_member.scss</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-13">app/assets/stylesheets/microcosms.scss</a>
    (3)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-14">app/controllers/application_controller.rb</a>
    (1)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-15">app/controllers/event_attendances_controller.rb</a>
    (48)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-16">app/controllers/events_controller.rb</a>
    (57)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-17">app/controllers/microcosm_member_controller.rb</a>
    (39)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-18">app/controllers/microcosms_controller.rb</a>
    (61)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-19">app/helpers/event_attendances_helper.rb</a>
    (2)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-20">app/helpers/events_helper.rb</a>
    (2)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-21">app/helpers/microcosm_member_helper.rb</a>
    (2)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-22">app/helpers/microcosms_helper.rb</a>
    (2)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-23">app/models/application_record.rb</a>
    (4)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-24">app/models/event.rb</a>
    (22)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-25">app/models/event_attendance.rb</a>
    (16)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-26">app/models/microcosm.rb</a>
    (43)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-27">app/models/microcosm_link.rb</a>
    (15)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-28">app/models/microcosm_member.rb</a>
    (30)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-29">app/views/events/_form.html.erb</a>
    (46)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-30">app/views/events/edit.html.erb</a>
    (0)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-31">app/views/events/index.html.erb</a>
    (32)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-32">app/views/events/new.html.erb</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-33">app/views/events/show.html.erb</a>
    (76)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-34">app/views/layouts/_header.html.erb</a>
    (1)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-35">app/views/microcosm_member/_form.html.erb</a>
    (20)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-36">app/views/microcosm_member/edit.html.erb</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-37">app/views/microcosms/_form.html.erb</a>
    (70)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-38">app/views/microcosms/edit.html.erb</a>
    (3)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-39">app/views/microcosms/index.html.erb</a>
    (28)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-40">app/views/microcosms/new.html.erb</a>
    (5)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-41">app/views/microcosms/show.html.erb</a>
    (115)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-42">app/views/microcosms/show_events.html.erb</a>
    (21)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-43">app/views/microcosms/show_members.html.erb</a>
    (25)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-44">config/cucumber.yml</a>
    (9)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-45">config/initializers/friendly_id.rb</a>
    (107)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-46">config/locales/en.yml</a>
    (9)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-47">config/routes.rb</a>
    (8)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-48">db/migrate/20190826032448_create_microcosms.rb</a>
    (13)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-49">db/migrate/20190831122812_create_microcosm_members.rb</a>
    (11)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-50">db/migrate/20190901143302_create_friendly_id_slugs.rb</a>
    (21)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-51">db/migrate/20190901151436_add_slug_to_microcosms.rb</a>
    (19)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-52">db/migrate/20190901163613_remove_key_from_microsoms.rb</a>
    (5)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-53">db/migrate/20190902200639_create_microcosm_links.rb</a>
    (11)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-54">db/migrate/20190902234710_remove_facebook_and_twitter_from_microsoms.rb</a>
    (6)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-55">db/migrate/20190903023243_role_in_microcosm_should_be_unique.rb</a>
    (14)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-56">db/migrate/20190903030453_add_location_to_microcosms.rb</a>
    (11)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-57">db/migrate/20190905160802_create_events.rb</a>
    (13)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-58">db/migrate/20190905224243_create_event_attendances.rb</a>
    (11)
  </li>
  <li>
    <strong>M</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-59">db/structure.sql</a>
    (391)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-60">features/admin.feature</a>
    (36)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-61">features/member.feature</a>
    (27)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-62">features/organizer.feature</a>
    (49)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-63">features/step_definitions/.gitkeep</a>
    (0)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-64">features/step_definitions/about_spec.rb</a>
    (175)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-65">features/support/env.rb</a>
    (61)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-66">features/visitor_about.feature</a>
    (53)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-67">lib/tasks/cucumber.rake</a>
    (76)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-68">script/cucumber</a>
    (11)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-69">test/controllers/event_attendances_controller_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-70">test/controllers/events_controller_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-71">test/controllers/microcosm_member_controller_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-72">test/controllers/microcosms_controller_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-73">test/factories/event_attendances.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-74">test/factories/events.rb</a>
    (9)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-75">test/factories/microcosm_links.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-76">test/factories/microcosm_members.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-77">test/factories/microcosms.rb</a>
    (9)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-78">test/models/event_attendance_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-79">test/models/event_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-80">test/models/microcosm_link_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-81">test/models/microcosm_member_test.rb</a>
    (7)
  </li>
  <li>
    <strong>A</strong>
    <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390/files#diff-82">test/models/microcosm_test.rb</a>
    (7)
  </li>
</ul>

<h4>Patch Links:</h4>
<ul>
  <li><a href='https://github.com/openstreetmap/openstreetmap-website/pull/2390.patch'>https://github.com/openstreetmap/openstreetmap-website/pull/2390.patch</a></li>
  <li><a href='https://github.com/openstreetmap/openstreetmap-website/pull/2390.diff'>https://github.com/openstreetmap/openstreetmap-website/pull/2390.diff</a></li>
</ul>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/openstreetmap/openstreetmap-website/pull/2390?email_source=notifications&email_token=AAK2OLM44MOSTNJRQC5HDLLQONILRA5CNFSM4JAHYW42YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HROJ5BA">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AAK2OLI42EX5G2Y4U2HGX6LQONILRANCNFSM4JAHYW4Q">unsubscribe</a>.<img src="https://github.com/notifications/beacon/AAK2OLJKER2Q7EJPGMIDBYLQONILRA5CNFSM4JAHYW42YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HROJ5BA.gif" height="1" width="1" alt="" /></p>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/openstreetmap/openstreetmap-website/pull/2390?email_source=notifications\u0026email_token=AAK2OLM44MOSTNJRQC5HDLLQONILRA5CNFSM4JAHYW42YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HROJ5BA",
"url": "https://github.com/openstreetmap/openstreetmap-website/pull/2390?email_source=notifications\u0026email_token=AAK2OLM44MOSTNJRQC5HDLLQONILRA5CNFSM4JAHYW42YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HROJ5BA",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>