diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..38bdb10
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,34 @@
+#FROM ubuntu:focal
+FROM ruby:3.1.2
+
+ENV REGULAR_USER=cvrails
+ENV REGULAR_USER_UID=1000
+ENV REGULAR_USER_GID=1000
+ENV REGULAR_USER_HOME=/home/${REGULAR_USER}
+ENV REGULAR_USER_APP_HOME=${REGULAR_USER_HOME}/app
+
+RUN groupadd -r --gid ${REGULAR_USER_GID} ${REGULAR_USER}
+RUN useradd --system --no-log-init --uid ${REGULAR_USER_UID} --gid ${REGULAR_USER_GID} --home-dir ${REGULAR_USER_HOME} --create-home --shell /bin/bash ${REGULAR_USER}
+
+RUN mkdir -p ${REGULAR_USER_APP_HOME} && chown -R ${REGULAR_USER}:${REGULAR_USER} ${REGULAR_USER_APP_HOME}
+
+RUN apt update && \
+ apt install -y texlive texinfo texlive-fonts-recommended texlive-latex-extra
+
+USER ${REGULAR_USER}
+WORKDIR ${REGULAR_USER_APP_HOME}
+
+# throw errors if Gemfile has been modified since Gemfile.lock
+RUN bundle config --global frozen 1
+
+# ENV RAILS_ENV=production
+COPY --chown=${REGULAR_USER}:${REGULAR_USER} Gemfile Gemfile.lock ./
+# RUN bundle config set --local without 'development test'
+RUN bundle install
+
+
+COPY --chown=${REGULAR_USER}:${REGULAR_USER} . .
+
+EXPOSE 3000
+
+CMD ["./docker-entrypoint.sh","puma"]
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
index a1e45e7..308d7ea 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
-ruby "3.1.1"
+ruby "3.1.2"
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.2", ">= 7.0.2.2"
diff --git a/app/controllers/work_experiences_controller.rb b/app/controllers/work_experiences_controller.rb
new file mode 100644
index 0000000..469e1a7
--- /dev/null
+++ b/app/controllers/work_experiences_controller.rb
@@ -0,0 +1,70 @@
+class WorkExperiencesController < ApplicationController
+ before_action :set_work_experience, only: %i[ show edit update destroy ]
+
+ # GET /work_experiences or /work_experiences.json
+ def index
+ @work_experiences = WorkExperience.all
+ end
+
+ # GET /work_experiences/1 or /work_experiences/1.json
+ def show
+ end
+
+ # GET /work_experiences/new
+ def new
+ @work_experience = WorkExperience.new
+ end
+
+ # GET /work_experiences/1/edit
+ def edit
+ end
+
+ # POST /work_experiences or /work_experiences.json
+ def create
+ @work_experience = WorkExperience.new(work_experience_params)
+
+ respond_to do |format|
+ if @work_experience.save
+ format.html { redirect_to work_experience_url(@work_experience), notice: "Work experience was successfully created." }
+ format.json { render :show, status: :created, location: @work_experience }
+ else
+ format.html { render :new, status: :unprocessable_entity }
+ format.json { render json: @work_experience.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # PATCH/PUT /work_experiences/1 or /work_experiences/1.json
+ def update
+ respond_to do |format|
+ if @work_experience.update(work_experience_params)
+ format.html { redirect_to work_experience_url(@work_experience), notice: "Work experience was successfully updated." }
+ format.json { render :show, status: :ok, location: @work_experience }
+ else
+ format.html { render :edit, status: :unprocessable_entity }
+ format.json { render json: @work_experience.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /work_experiences/1 or /work_experiences/1.json
+ def destroy
+ @work_experience.destroy
+
+ respond_to do |format|
+ format.html { redirect_to work_experiences_url, notice: "Work experience was successfully destroyed." }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+ # Use callbacks to share common setup or constraints between actions.
+ def set_work_experience
+ @work_experience = WorkExperience.find(params[:id])
+ end
+
+ # Only allow a list of trusted parameters through.
+ def work_experience_params
+ params.require(:work_experience).permit(:period, :employer, :title, :technologies, :achivements)
+ end
+end
diff --git a/app/helpers/work_experiences_helper.rb b/app/helpers/work_experiences_helper.rb
new file mode 100644
index 0000000..dfccafb
--- /dev/null
+++ b/app/helpers/work_experiences_helper.rb
@@ -0,0 +1,2 @@
+module WorkExperiencesHelper
+end
diff --git a/app/models/work_experience.rb b/app/models/work_experience.rb
new file mode 100644
index 0000000..b82b85d
--- /dev/null
+++ b/app/models/work_experience.rb
@@ -0,0 +1,2 @@
+class WorkExperience < ApplicationRecord
+end
diff --git a/app/views/work_experiences/_form.html.erb b/app/views/work_experiences/_form.html.erb
new file mode 100644
index 0000000..7bc0948
--- /dev/null
+++ b/app/views/work_experiences/_form.html.erb
@@ -0,0 +1,42 @@
+<%= form_with(model: work_experience) do |form| %>
+ <% if work_experience.errors.any? %>
+
+
<%= pluralize(work_experience.errors.count, "error") %> prohibited this work_experience from being saved:
+
+
+ <% work_experience.errors.each do |error| %>
+ - <%= error.full_message %>
+ <% end %>
+
+
+ <% end %>
+
+
+ <%= form.label :period, style: "display: block" %>
+ <%= form.text_field :period %>
+
+
+
+ <%= form.label :employer, style: "display: block" %>
+ <%= form.text_field :employer %>
+
+
+
+ <%= form.label :title, style: "display: block" %>
+ <%= form.text_field :title %>
+
+
+
+ <%= form.label :technologies, style: "display: block" %>
+ <%= form.text_field :technologies %>
+
+
+
+ <%= form.label :achivements, style: "display: block" %>
+ <%= form.text_field :achivements %>
+
+
+
+ <%= form.submit %>
+
+<% end %>
diff --git a/app/views/work_experiences/_work_experience.html.erb b/app/views/work_experiences/_work_experience.html.erb
new file mode 100644
index 0000000..731ad88
--- /dev/null
+++ b/app/views/work_experiences/_work_experience.html.erb
@@ -0,0 +1,27 @@
+
+
+ Period:
+ <%= work_experience.period %>
+
+
+
+ Employer:
+ <%= work_experience.employer %>
+
+
+
+ Title:
+ <%= work_experience.title %>
+
+
+
+ Technologies:
+ <%= work_experience.technologies %>
+
+
+
+ Achivements:
+ <%= work_experience.achivements %>
+
+
+
diff --git a/app/views/work_experiences/_work_experience.json.jbuilder b/app/views/work_experiences/_work_experience.json.jbuilder
new file mode 100644
index 0000000..2ae0997
--- /dev/null
+++ b/app/views/work_experiences/_work_experience.json.jbuilder
@@ -0,0 +1,2 @@
+json.extract! work_experience, :id, :period, :employer, :title, :technologies, :achivements, :created_at, :updated_at
+json.url work_experience_url(work_experience, format: :json)
diff --git a/app/views/work_experiences/edit.html.erb b/app/views/work_experiences/edit.html.erb
new file mode 100644
index 0000000..33295e4
--- /dev/null
+++ b/app/views/work_experiences/edit.html.erb
@@ -0,0 +1,10 @@
+Editing work experience
+
+<%= render "form", work_experience: @work_experience %>
+
+
+
+
+ <%= link_to "Show this work experience", @work_experience %> |
+ <%= link_to "Back to work experiences", work_experiences_path %>
+
diff --git a/app/views/work_experiences/index.html.erb b/app/views/work_experiences/index.html.erb
new file mode 100644
index 0000000..dfdcd70
--- /dev/null
+++ b/app/views/work_experiences/index.html.erb
@@ -0,0 +1,14 @@
+<%= notice %>
+
+Work experiences
+
+
+ <% @work_experiences.each do |work_experience| %>
+ <%= render work_experience %>
+
+ <%= link_to "Show this work experience", work_experience %>
+
+ <% end %>
+
+
+<%= link_to "New work experience", new_work_experience_path %>
diff --git a/app/views/work_experiences/index.json.jbuilder b/app/views/work_experiences/index.json.jbuilder
new file mode 100644
index 0000000..34d7b73
--- /dev/null
+++ b/app/views/work_experiences/index.json.jbuilder
@@ -0,0 +1 @@
+json.array! @work_experiences, partial: "work_experiences/work_experience", as: :work_experience
diff --git a/app/views/work_experiences/new.html.erb b/app/views/work_experiences/new.html.erb
new file mode 100644
index 0000000..263ce47
--- /dev/null
+++ b/app/views/work_experiences/new.html.erb
@@ -0,0 +1,9 @@
+New work experience
+
+<%= render "form", work_experience: @work_experience %>
+
+
+
+
+ <%= link_to "Back to work experiences", work_experiences_path %>
+
diff --git a/app/views/work_experiences/show.html.erb b/app/views/work_experiences/show.html.erb
new file mode 100644
index 0000000..7fd7f02
--- /dev/null
+++ b/app/views/work_experiences/show.html.erb
@@ -0,0 +1,10 @@
+<%= notice %>
+
+<%= render @work_experience %>
+
+
+ <%= link_to "Edit this work experience", edit_work_experience_path(@work_experience) %> |
+ <%= link_to "Back to work experiences", work_experiences_path %>
+
+ <%= button_to "Destroy this work experience", @work_experience, method: :delete %>
+
diff --git a/app/views/work_experiences/show.json.jbuilder b/app/views/work_experiences/show.json.jbuilder
new file mode 100644
index 0000000..74ff57f
--- /dev/null
+++ b/app/views/work_experiences/show.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "work_experiences/work_experience", work_experience: @work_experience
diff --git a/config/routes.rb b/config/routes.rb
index 262ffd5..6238958 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,4 +1,5 @@
Rails.application.routes.draw do
+ resources :work_experiences
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
diff --git a/db/migrate/20220830202251_create_work_experiences.rb b/db/migrate/20220830202251_create_work_experiences.rb
new file mode 100644
index 0000000..3e0e7d3
--- /dev/null
+++ b/db/migrate/20220830202251_create_work_experiences.rb
@@ -0,0 +1,13 @@
+class CreateWorkExperiences < ActiveRecord::Migration[7.0]
+ def change
+ create_table :work_experiences do |t|
+ t.string :period
+ t.string :employer
+ t.string :title
+ t.string :technologies
+ t.string :achivements
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 0000000..9cd3f76
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,24 @@
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema[7.0].define(version: 2022_08_30_202251) do
+ create_table "work_experiences", force: :cascade do |t|
+ t.string "period"
+ t.string "employer"
+ t.string "title"
+ t.string "technologies"
+ t.string "achivements"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+end
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..2c32255
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,11 @@
+version: '3'
+
+services:
+ web:
+ image: latext-resumes
+ build: .
+ ports:
+ - 3000:3000
+ command: tail -F /home/cvrails/app/log/development.log
+ volumes:
+ - ./:/home/cvrails/app
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
new file mode 100755
index 0000000..a3e279b
--- /dev/null
+++ b/docker-entrypoint.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# TODO: Move the tidying up of sidekiq config file onto a function
+# TODO: Have the bundle install for dev- prefix argument
+
+before_commands () {
+ if [ "$RAILS_ENV" = 'development' ]; then
+ echo "App in development mode running bundle install and yarn install to update components"
+ bundle install > /dev/null
+ yarn install > /dev/null
+ fi
+}
+
+set -e
+
+if [ "$1" = 'dev-server' ]; then
+ before_commands
+ exec rails s -b 0.0.0.0 -p 3000
+elif [ "$1" = 'puma' ]; then
+ before_commands
+ exec bundle exec puma -C config/puma.rb
+elif [ "$1" = 'rails' ]; then
+ echo "Rails command detected!"
+ before_commands
+ exec bundle exec "$@"
+elif [ "$1" = 'rake' ]; then
+ echo "Rake command detected!"
+ before_commands
+ exec bundle exec "$@"
+else
+ exec bundle exec puma -C config/puma.rb
+fi
+
+exec "$@"
diff --git a/test/controllers/work_experiences_controller_test.rb b/test/controllers/work_experiences_controller_test.rb
new file mode 100644
index 0000000..6d86a56
--- /dev/null
+++ b/test/controllers/work_experiences_controller_test.rb
@@ -0,0 +1,48 @@
+require "test_helper"
+
+class WorkExperiencesControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @work_experience = work_experiences(:one)
+ end
+
+ test "should get index" do
+ get work_experiences_url
+ assert_response :success
+ end
+
+ test "should get new" do
+ get new_work_experience_url
+ assert_response :success
+ end
+
+ test "should create work_experience" do
+ assert_difference("WorkExperience.count") do
+ post work_experiences_url, params: { work_experience: { achivements: @work_experience.achivements, employer: @work_experience.employer, period: @work_experience.period, technologies: @work_experience.technologies, title: @work_experience.title } }
+ end
+
+ assert_redirected_to work_experience_url(WorkExperience.last)
+ end
+
+ test "should show work_experience" do
+ get work_experience_url(@work_experience)
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get edit_work_experience_url(@work_experience)
+ assert_response :success
+ end
+
+ test "should update work_experience" do
+ patch work_experience_url(@work_experience), params: { work_experience: { achivements: @work_experience.achivements, employer: @work_experience.employer, period: @work_experience.period, technologies: @work_experience.technologies, title: @work_experience.title } }
+ assert_redirected_to work_experience_url(@work_experience)
+ end
+
+ test "should destroy work_experience" do
+ assert_difference("WorkExperience.count", -1) do
+ delete work_experience_url(@work_experience)
+ end
+
+ assert_redirected_to work_experiences_url
+ end
+end
diff --git a/test/fixtures/work_experiences.yml b/test/fixtures/work_experiences.yml
new file mode 100644
index 0000000..14549ff
--- /dev/null
+++ b/test/fixtures/work_experiences.yml
@@ -0,0 +1,15 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ period: MyString
+ employer: MyString
+ title: MyString
+ technologies: MyString
+ achivements: MyString
+
+two:
+ period: MyString
+ employer: MyString
+ title: MyString
+ technologies: MyString
+ achivements: MyString
diff --git a/test/models/work_experience_test.rb b/test/models/work_experience_test.rb
new file mode 100644
index 0000000..5affa04
--- /dev/null
+++ b/test/models/work_experience_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class WorkExperienceTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/system/work_experiences_test.rb b/test/system/work_experiences_test.rb
new file mode 100644
index 0000000..4f0fd62
--- /dev/null
+++ b/test/system/work_experiences_test.rb
@@ -0,0 +1,49 @@
+require "application_system_test_case"
+
+class WorkExperiencesTest < ApplicationSystemTestCase
+ setup do
+ @work_experience = work_experiences(:one)
+ end
+
+ test "visiting the index" do
+ visit work_experiences_url
+ assert_selector "h1", text: "Work experiences"
+ end
+
+ test "should create work experience" do
+ visit work_experiences_url
+ click_on "New work experience"
+
+ fill_in "Achivements", with: @work_experience.achivements
+ fill_in "Employer", with: @work_experience.employer
+ fill_in "Period", with: @work_experience.period
+ fill_in "Technologies", with: @work_experience.technologies
+ fill_in "Title", with: @work_experience.title
+ click_on "Create Work experience"
+
+ assert_text "Work experience was successfully created"
+ click_on "Back"
+ end
+
+ test "should update Work experience" do
+ visit work_experience_url(@work_experience)
+ click_on "Edit this work experience", match: :first
+
+ fill_in "Achivements", with: @work_experience.achivements
+ fill_in "Employer", with: @work_experience.employer
+ fill_in "Period", with: @work_experience.period
+ fill_in "Technologies", with: @work_experience.technologies
+ fill_in "Title", with: @work_experience.title
+ click_on "Update Work experience"
+
+ assert_text "Work experience was successfully updated"
+ click_on "Back"
+ end
+
+ test "should destroy Work experience" do
+ visit work_experience_url(@work_experience)
+ click_on "Destroy this work experience", match: :first
+
+ assert_text "Work experience was successfully destroyed"
+ end
+end