Created
December 16, 2015 05:57
-
-
Save Harrisonl/d44b038248a41a42457c to your computer and use it in GitHub Desktop.
Code Examples + RSpec Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## This is an extract from my online content platform. This model here deals with the Project object. The project object is used to | |
## describe a request for a new piece of content from a client. It is an important object in the application and is one which a lot | |
## of other models and objects depend on.This model also provides various methods which can be used throughout the application. | |
class Project < ActiveRecord::Base | |
## Validations | |
validates_presence_of :title, :brief, :project_tone, :client_email | |
## Relationships | |
belongs_to :client, class_name: "User", foreign_key: :client_id | |
belongs_to :freelancer, class_name: "Freelancer", foreign_key: :freelancer_id | |
has_many :payments | |
has_many :submissions | |
has_one :conversation, dependent: :delete | |
has_one :review, dependent: :delete | |
before_create :generate_uid | |
## Calculate the cost of the project depending on its length and price per word (PPW) | |
## Used in project#create | |
def calculate_project_cost(options={}) | |
cpw = 3 | |
quality = options[:quality] | |
type = options[:type] | |
length = options[:length] | |
tat = options[:tat] | |
if quality == "Normal" && type != "Ebook" | |
self.project_cost = cpw * length.to_i | |
elsif quality == "Premium" && type != "Ebook" | |
cpw = 5 | |
self.project_cost = cpw * length.to_i | |
elsif quality == "Exceptional" && type != "Ebook" | |
cpw = 7 | |
self.project_cost = cpw * length.to_i | |
elsif type == "Ebook" | |
cpw = 4 | |
self.project_cost = cpw * length.to_i | |
end | |
self.project_cost = self.project_cost * 0.9 if length.to_i >= 6000 && tat == "normal" | |
self.project_cost = self.project_cost * 1.1 if tat == "fast" && length < 6000 | |
self.save | |
end | |
# Creates a conversation when a new project is successfully created | |
# See ProjectsController#create for more | |
def create_conversation_for_project | |
c = Conversation.new | |
c.freelancer_id = self.freelancer_id | |
c.user_id = self.client_id | |
c.project_id = self.id | |
c.save | |
end | |
def mark_as_paid | |
self.paid = true | |
self.save | |
end | |
def in_progress? | |
self.in_progress | |
end | |
def completed? | |
self.completed | |
end | |
## Marks the project as complete and add's the earnt commission to the freelancers owed_commission attribute | |
def mark_project_complete | |
freelancer = self.freelancer | |
self.completed = true | |
self.completed_date = Date.today | |
self.in_progress = false | |
freelancer.owed_commission = freelancer.owed_commission + (self.project_cost * freelancer.earning_rate) | |
freelancer.save | |
self.save | |
end | |
# Checks if there is a freelancer assigned | |
def freelancer? | |
self.freelancer | |
end | |
# Checks if there are any submissions present | |
def any_submissions? | |
self.submissions.any? | |
end | |
def assign_writer(freelancer) | |
self.freelancer = freelancer | |
self.save | |
end | |
def request_due | |
created = self.created_at | |
tat = self.tat | |
if tat == "normal" | |
return "#{created + 3.days}" | |
elsif tat == "fast" | |
return "#{created + 1.days}" | |
end | |
end | |
private | |
## Create a random UID for the project | |
def generate_uid | |
self.uid = loop do | |
token = SecureRandom.urlsafe_base64 | |
break token unless Project.exists?(uid: token) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Here is the corresponding test file for Project Model. | |
require 'rails_helper' | |
RSpec.describe Project do | |
it { should validate_presence_of(:title) } | |
it { should validate_presence_of(:brief) } | |
it { should validate_presence_of(:project_type) } | |
it { should validate_presence_of(:project_length) } | |
it { should validate_presence_of(:project_quality) } | |
it { should validate_presence_of(:project_tone) } | |
describe "#calculate_project_cost(options={}" do | |
## ASSUME LENGTH IS 100 FOR ALL TESTS | |
it "sets cost to 300 for normal quality" do | |
project = Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Normal") | |
project.calculate_project_cost(quality: project.project_quality, length: project.project_length, tat: "normal", type: project.project_type) | |
project.reload | |
expect(project.project_cost).to eq(300) | |
end | |
it "sets the cost 500 for premium quality" do | |
project = Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Premium") | |
project.calculate_project_cost(quality: project.project_quality, length: project.project_length, tat: "normal", type: project.project_type) | |
project.reload | |
expect(project.project_cost).to eq(500) | |
end | |
it "sets the cost to 700 for exceptional quality" do | |
project = Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional") | |
project.calculate_project_cost(quality: project.project_quality, length: project.project_length, tat: "normal", type: project.project_type) | |
project.reload | |
expect(project.project_cost).to eq(700) | |
end | |
it "sets the cost to 400 for an ebook type" do | |
project = Project.create(title: "test", brief: "123", project_type: "Ebook", project_length: "100", project_tone: "123", project_quality: "Exceptional") | |
project.calculate_project_cost(quality: project.project_quality, length: project.project_length, tat: "normal", type: project.project_type) | |
project.reload | |
expect(project.project_cost).to eq(400) | |
end | |
it "adds 1000 to the cost if the tat is fast" do | |
project = Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional") | |
project.calculate_project_cost(quality: project.project_quality, length: project.project_length, tat: "fast", type: project.project_type) | |
project.reload | |
expect(project.project_cost).to eq(1700) | |
end | |
end | |
describe "#create_conversation_for_project" do | |
let(:alice) { FactoryGirl.create(:client) } | |
let(:bob) { FactoryGirl.create(:freelancer) } | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional", freelancer_id: bob.id, client_id: alice.id) } | |
before do | |
project.create_conversation_for_project | |
end | |
it "should create a new conversation that belongs to the project" do | |
expect(project.conversation).to_not be_nil | |
end | |
it "should set the user id to the projects client" do | |
expect(Conversation.first.user_id).to eq(alice.id) | |
end | |
it "should set the freelancer id to the projects freelancer" do | |
expect(Conversation.first.freelancer_id).to eq(bob.id) | |
end | |
it "should set the project id to the projects id" do | |
expect(Conversation.first.project_id).to eq(project.id) | |
end | |
end | |
describe "#in_progress" do | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional") } | |
it "returns true if in progress is true" do | |
project.in_progress = true | |
project.save | |
expect(project.in_progress?).to eq(true) | |
end | |
it "returns false if in progress is false" do | |
project.in_progress = false | |
project.save | |
expect(project.in_progress?).to eq(false) | |
end | |
end | |
describe "#completed?" do | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional") } | |
it "returns true if completed is true" do | |
project.completed = true | |
project.save | |
expect(project.completed).to eq(true) | |
end | |
it "returns false if completed is false" do | |
project.completed = false | |
project.save | |
expect(project.completed).to eq(false) | |
end | |
end | |
describe "#mark_complete" do | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional") } | |
it "sets the project's completed status to true" do | |
project.mark_complete | |
expect(project.completed).to eq(true) | |
end | |
it "sets the completed date to todays date" do | |
project.mark_complete | |
expect(project.completed_date).to eq(Date.today) | |
end | |
end | |
describe "#freelancer?" do | |
let(:bob) { FactoryGirl.create(:freelancer) } | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional", freelancer_id: bob.id) } | |
it "returns the freelancer if one is assigned" do | |
expect(project.freelancer?).to eq(bob) | |
end | |
it "returns nil if no freelancer is assigned" do | |
project.freelancer = nil | |
project.save | |
expect(project.freelancer?).to be_nil | |
end | |
end | |
describe "#any_submissions?" do | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional") } | |
it "returns true if there are submissions" do | |
submission = FactoryGirl.create(:submission, project_id: project.id) | |
expect(project.any_submissions?).to eq(true) | |
end | |
it "returns false if there are no submissions" do | |
expect(project.any_submissions?).to eq(false) | |
end | |
end | |
describe "#assign_writer(freelancer)" do | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional") } | |
it "assigns the projects freelancer to the passed in freelancer" do | |
bob = FactoryGirl.create(:freelancer) | |
project.assign_writer(bob) | |
expect(Project.first.freelancer).to eq(bob) | |
end | |
end | |
describe "#request_due" do | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional", tat: "normal") } | |
it "returns 3 days from today if the tat is normal" do | |
expect(project.request_due).to eq("#{project.created_at + 3.days}") | |
end | |
it "returns 1 day from today if the tat is fast" do | |
project.tat = "fast" | |
project.save | |
expect(project.request_due).to eq("#{project.created_at + 1.days}") | |
end | |
end | |
describe "#generate_uid" do | |
let(:project) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional", tat: "normal") } | |
let(:project2) { Project.create(title: "test", brief: "123", project_type: "article", project_length: "100", project_tone: "123", project_quality: "Exceptional", tat: "normal", uid: project.uid) } | |
it "should set the projects uid" do | |
expect(project.uid).to_not be_blank | |
end | |
it "should make sure it does not equal any other proejcts uid" do | |
expect(project2.uid).to_not eq(project.uid) | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment